Hi experts,
I'm trying to display different images while running the graph (like single-cam app example).
How I want to do is:
1. receive 4 cv::mat
2. resize and concat into 1 cv::mat
3. convert into vx image
4. display this image
Then keep looping through it.
Last time you provided the code for image display, but it can only display a fixed image.
/* * * Copyright (c) 2017 Texas Instruments Incorporated * * All rights reserved not granted herein. * * Limited License. * * Texas Instruments Incorporated grants a world-wide, royalty-free, non-exclusive * license under copyrights and patents it now or hereafter owns or controls to make, * have made, use, import, offer to sell and sell ("Utilize") this software subject to the * terms herein. With respect to the foregoing patent license, such license is granted * solely to the extent that any such patent is necessary to Utilize the software alone. * The patent license shall not apply to any combinations which include this software, * other than combinations with devices manufactured by or for TI ("TI Devices"). * No hardware patent is licensed hereunder. * * Redistributions must preserve existing copyright notices and reproduce this license * (including the above copyright notice and the disclaimer and (if applicable) source * code license limitations below) in the documentation and/or other materials provided * with the distribution * * Redistribution and use in binary form, without modification, are permitted provided * that the following conditions are met: * * * No reverse engineering, decompilation, or disassembly of this software is * permitted with respect to any software provided in binary form. * * * any redistribution and use are licensed by TI for use only with TI Devices. * * * Nothing shall obligate TI to provide you with source code for the software * licensed and provided to you in object code. * * If software source code is provided to you, modification and redistribution of the * source code are permitted provided that the following conditions are met: * * * any redistribution and use of the source code, including any resulting derivative * works, are licensed by TI for use only with TI Devices. * * * any redistribution and use of any object code compiled from the source code * and any resulting derivative works, are licensed by TI for use only with TI Devices. * * Neither the name of Texas Instruments Incorporated nor the names of its suppliers * * may be used to endorse or promote products derived from this software without * specific prior written permission. * * DISCLAIMER. * * THIS SOFTWARE IS PROVIDED BY TI AND TI'S LICENSORS "AS IS" AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL TI AND TI'S LICENSORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * */ #include <stdio.h> #include <VX/vx.h> #include <TI/tivx.h> #include <vx_internal.h> #include <TI/video_io_kernels.h> #include <TI/video_io_display.h> #include <utils/app_init/include/app_init.h> static vx_status readYUVInput(char* file_name, vx_image in_img) { vx_status status; FILE * fp = fopen(file_name,"rb"); vx_int32 j; if(fp == NULL) { printf("Unable to open file %s \n", file_name); return (VX_FAILURE); } vx_rectangle_t rect; vx_imagepatch_addressing_t image_addr; vx_map_id map_id; void * data_ptr; vx_uint32 img_width; vx_uint32 img_height; vx_uint32 num_bytes = 0; vxQueryImage(in_img, VX_IMAGE_WIDTH, &img_width, sizeof(vx_uint32)); vxQueryImage(in_img, VX_IMAGE_HEIGHT, &img_height, sizeof(vx_uint32)); printf("%d x %d \n", img_width, img_height); rect.start_x = 0; rect.start_y = 0; rect.end_x = img_width; rect.end_y = img_height; status = vxMapImagePatch(in_img, &rect, 0, &map_id, &image_addr, &data_ptr, VX_WRITE_ONLY, VX_MEMORY_TYPE_HOST, VX_NOGAP_X); /* Copy Luma */ for (j = 0; j < img_height; j++) { num_bytes += fread(data_ptr, 1, img_width, fp); data_ptr += image_addr.stride_y; } printf("data_ptr = 0x%p\n", data_ptr); if(num_bytes != (img_width*img_height)) { printf("Luma bytes read = %d, expected = %d\n", num_bytes, img_width*img_height); } else { printf("Luma bytes success read = %d, expected = %d\n", num_bytes, img_width*img_height); } vxUnmapImagePatch(in_img, map_id); rect.start_x = 0; rect.start_y = 0; rect.end_x = img_width; rect.end_y = img_height / 2; status = vxMapImagePatch(in_img, &rect, 1, &map_id, &image_addr, &data_ptr, VX_WRITE_ONLY, VX_MEMORY_TYPE_HOST, VX_NOGAP_X); /* Copy CbCr */ num_bytes = 0; for (j = 0; j < img_height/2; j++) { num_bytes += fread(data_ptr, 1, img_width, fp); data_ptr += image_addr.stride_y; } printf("U data_ptr = 0x%p\n", data_ptr); if(num_bytes != (img_width*img_height/2)) { printf("CbCr bytes read = %d, expected = %d\n", num_bytes, img_width*img_height/2); } else { printf("CbCr bytes success read = %d, expected = %d\n", num_bytes, img_width*img_height/2); } vxUnmapImagePatch(in_img, map_id); fclose(fp); return(status); } static vx_status writeYUVInput(char* file_name, vx_image out_img) { vx_status status; FILE * fp = fopen(file_name,"wb"); vx_int32 j; if(fp == NULL) { printf("Unable to open file %s \n", file_name); return (VX_FAILURE); } vx_rectangle_t rect; vx_imagepatch_addressing_t image_addr; vx_map_id map_id; void * data_ptr; vx_uint32 img_width; vx_uint32 img_height; vx_uint32 num_bytes = 0; vxQueryImage(out_img, VX_IMAGE_WIDTH, &img_width, sizeof(vx_uint32)); vxQueryImage(out_img, VX_IMAGE_HEIGHT, &img_height, sizeof(vx_uint32)); rect.start_x = 0; rect.start_y = 0; rect.end_x = img_width; rect.end_y = img_height; status = vxMapImagePatch(out_img, &rect, 0, &map_id, &image_addr, &data_ptr, VX_READ_ONLY, VX_MEMORY_TYPE_HOST, VX_NOGAP_X); /* Copy Luma */ for (j = 0; j < img_height; j++) { num_bytes += fwrite(data_ptr, 1, img_width, fp); data_ptr += image_addr.stride_y; } printf("O data_ptr = 0x%p\n", data_ptr); if(num_bytes != (img_width*img_height)) printf("Luma bytes written = %d, expected = %d\n", num_bytes, img_width*img_height); vxUnmapImagePatch(out_img, map_id); rect.start_x = 0; rect.start_y = 0; rect.end_x = img_width; rect.end_y = img_height / 2; status = vxMapImagePatch(out_img, &rect, 1, &map_id, &image_addr, &data_ptr, VX_READ_ONLY, VX_MEMORY_TYPE_HOST, VX_NOGAP_X); /* Copy CbCr */ num_bytes = 0; for (j = 0; j < img_height/2; j++) { num_bytes += fwrite(data_ptr, 1, img_width, fp); data_ptr += image_addr.stride_y; } printf("OU data_ptr = 0x%p\n", data_ptr); if(num_bytes != (img_width*img_height/2)) printf("CbCr bytes written = %d, expected = %d\n", num_bytes, img_width*img_height/2); vxUnmapImagePatch(out_img, map_id); fclose(fp); return(status); } /** * \brief Tutorial Entry Point */ int main() { int status = 0; tivx_display_params_t display_params; vx_user_data_object display_param_obj; vx_node displayNode; vx_image display_image; int i = 0; vx_imagepatch_addressing_t input_image_addr, display_image_addr; tivx_obj_desc_image_t *input_obj_desc = NULL; tivx_obj_desc_image_t *output_obj_desc = NULL; status = appInit(); if(status == VX_SUCCESS) { vx_context context = vxCreateContext(); tivxVideoIOLoadKernels(context); vx_graph graph = vxCreateGraph(context); memset(&display_params, 0, sizeof(tivx_display_params_t)); display_params.opMode = TIVX_KERNEL_DISPLAY_ZERO_BUFFER_COPY_MODE; display_params.pipeId = 2; display_params.outHeight = OUTPUT_TEX_HEIGHT; display_params.outWidth = OUTPUT_TEX_WIDTH; display_params.posX = 0; display_params.posY = 0; display_image = vxCreateImage(context, OUTPUT_TEX_WIDTH, OUTPUT_TEX_HEIGHT, VX_DF_IMAGE_NV12); // Display Initialization display_param_obj = vxCreateUserDataObject(context, "tivx_display_params_t", sizeof(tivx_display_params_t), &display_params); displayNode = tivxDisplayNode(graph, display_param_obj, display_image); if(status == VX_SUCCESS) { status = vxSetNodeTarget(displayNode, VX_TARGET_STRING, TIVX_TARGET_DISPLAY1); printf("Display Set Target done\n"); } if(status == VX_SUCCESS) { status = vxVerifyGraph(graph); printf("Verify Graph\n"); } status = readYUVInput(IN_FILE_NAME, display_image); printf("Input file filled\n"); if(status == VX_SUCCESS) { status = writeYUVInput(OUT_FILE_NAME, display_image); printf("Output file to test if the image read correctly before sending to display\n"); } if(status == VX_SUCCESS) { if(status == VX_SUCCESS) { for(i = 0; i < LOOPCOUNT; i++) { status = vxProcessGraph(graph); } } } if(status == VX_SUCCESS) { status = vxReleaseUserDataObject(&display_param_obj); status |= vxReleaseImage(&display_image); status |= vxReleaseNode(&displayNode); status |= vxReleaseGraph(&graph); tivxVideoIOUnLoadKernels(context); status |= vxReleaseContext(&context); printf("Release Graph and context\n"); } } else { printf("app init fail \n"); } return 0; }
Is it able to keep displaying the new image without keep creating and deleting the graph?
Thanks.