Visionworks "Hello world" program

Hi, TX1 has a preinstall SFM sample for visionworks which i found bit complex ;)

Can some one post a very basic “Hello world” kind of program

(read an image do some operation very simple)

This page has a video, the first example they mention is histogram equalization, which seems to be pretty close to what you’re asking for: https://www.brainshark.com/nvidia/vwb-simplecv

I had the same question, and it took me a couple of days to get this code running. Example code and how-to’s are apparently in extremely short supply. I used the Khronos OpenVX reference, the Nvidia VisionWorks reference (downloaded from Nvidia site), and the OpenVX whitepaper found from the Khronos OpenVX page under the “resources” tab.

https://www.khronos.org/registry/vx/specs/1.0/html/index.html

https://developer.nvidia.com/embedded/visionworks

http://people.csail.mit.edu/kapu/papers/openvx_optimization_2014.pdf

I used a stereo image pair from the Middlebury dataset (in my case, the “cones” images from the 2003 dataset, but with one pair renamed “left.png” and “right.png”) found at the following website:

http://vision.middlebury.edu/stereo/data/

Here is my code:

#include <stdio.h>
#include <NVX/nvx.h>
#include <NVX/nvx_opencv_interop.hpp>
#include <opencv2/opencv.hpp>

int main(){
        // read stereo images in as grayscale (CV_8U):
        cv::Mat mat_l = cv::imread("left.png",0);
        cv::Mat mat_r = cv::imread("right.png",0);
        if(mat_l.empty() || mat_r.empty()){
                printf("ERROR! failed to read one or both images, exiting...\n");
                return 1;
        } 
        // read image size
        int w = mat_l.cols;
        int h = mat_l.rows;

        // create context, and graph
        vx_context c = vxCreateContext() ;
        vx_graph g = vxCreateGraph(c);

        /* create images; virtual images are for intermediate images that
           aren't direct inputs or outputs from the graph, but due to the
           simplicity of our graph, there are no intermediate images */
        vx_image left = nvx::createImageFromMat(c, mat_l);
        vx_image right = nvx::createImageFromMat(c, mat_r);
        vx_image disp = vxCreateImage (c , w, h, VX_DF_IMAGE_S16);
        // this is an example of a virtual image, if you needed one
        //vx_image intermed_im = vxCreateVirtualImage (g , 0, 0, VX_DF_IMAGE_VIRT);

        // values taken from demo installed by libvisionworks
        vx_int32        minD = 0;
        vx_int32        maxD = 64;
        vx_int32        P1 = 8;
        vx_int32        P2 = 109;
        vx_int32        sad = 5;
        vx_int32        clip = 31;
        vx_int32        max_diff = 32000;
        vx_int32        uniqueness = 0;

        // create the nodes in the graph
        vx_node n [] = {
                // there's only one node on this graph...
                nvxSemiGlobalMatchingNode(g, left, right, disp, minD, maxD, 
                        P1, P2, sad, clip, max_diff, uniqueness, NVX_SCANLINE_ALL),
        };

        // verify then process the graph once
        printf("verifying graph now...\n");
        if(vxVerifyGraph(g) == VX_SUCCESS){
                printf("graph verified, processing now...\n");
                printf("vxProcessGraph returns %d\n",vxProcessGraph (g));
        }else{
                printf("graph verification failed, exiting...\n");
                vxReleaseGraph(&g);
                vxReleaseImage(&left);
                vxReleaseImage(&right);
                vxReleaseImage(&disp);
                vxReleaseContext(&c);
                return 2;
        }

        /* I'm using Nvidia's nvx_opencv_interop.hpp header file
           to get a cv::Mat from a vx_image.  It seems there is also
           something called NVXIO that looked more powerful/complicated */
        nvx::ImageToMatMapper mapper(disp);
        cv::Mat mat_d = mapper.getMat();
        // to properly scale the image for viewing, we need min and max
        double minval;
        double maxval;
        cv::minMaxLoc(mat_d, &minval, &maxval);

        // now we need to scale from sint16 to uint8 before writing
        cv::Mat mat_im(mat_d.rows,mat_d.cols,CV_8U);
        mat_im = 255*(mat_d-minval)/(maxval-minval);
        // now write using opencv
        cv::imwrite("out.png",mat_im);

        // I'm not completely sure that I'm releasing everything correctly
        vxReleaseGraph(&g);
        vxReleaseImage(&left);
        vxReleaseImage(&right);
        vxReleaseImage(&disp);
        vxReleaseContext(&c);

        return 0;
}

I complied it on a TX1 with the latest libopencv4tegra and libvisionworks installation with the following command:

g++ `pkg-config visionworks opencv --cflags --libs` test.cpp -o test `pkg-config visionworks opencv --libs`

And lastly, I was not able to find some sort of vx_perror() function, so I wrote my own that uses the comments in the header file as explanations of the different error codes:

void vx_perror(int val){
        switch(val){
                case    VX_STATUS_MIN                       : printf("Error: VX_STATUS_MIN               Indicates the lower bound of status codes in VX. Used for bounds checks only. \n"); break;
                case    VX_ERROR_REFERENCE_NONZERO          : printf("Error: VX_ERROR_REFERENCE_NONZERO  Indicates that an operation did not complete due to a reference count being non-zero. \n"); break;
                case    VX_ERROR_MULTIPLE_WRITERS           : printf("Error: VX_ERROR_MULTIPLE_WRITERS   Indicates that the graph has more than one node outputting to the same data object. This is an invalid graph structure. \n"); break;
                case    VX_ERROR_GRAPH_ABANDONED            : printf("Error: VX_ERROR_GRAPH_ABANDONED    Indicates that the graph is stopped due to an error or a callback that abandoned execution. \n"); break;
                case    VX_ERROR_GRAPH_SCHEDULED            : printf("Error: VX_ERROR_GRAPH_SCHEDULED    Indicates that the supplied graph already has been scheduled and may be currently executing. \n"); break;
                case    VX_ERROR_INVALID_SCOPE              : printf("Error: VX_ERROR_INVALID_SCOPE      Indicates that the supplied parameter is from another scope and cannot be used in the current scope. \n"); break;
                case    VX_ERROR_INVALID_NODE               : printf("Error: VX_ERROR_INVALID_NODE       Indicates that the supplied node could not be created.\n"); break;
                case    VX_ERROR_INVALID_GRAPH              : printf("Error: VX_ERROR_INVALID_GRAPH      Indicates that the supplied graph has invalid connections (cycles). \n"); break;
                case    VX_ERROR_INVALID_TYPE               : printf("Error: VX_ERROR_INVALID_TYPE       Indicates that the supplied type parameter is incorrect. \n"); break;
                case    VX_ERROR_INVALID_VALUE              : printf("Error: VX_ERROR_INVALID_VALUE      Indicates that the supplied parameter has an incorrect value. \n"); break;
                case    VX_ERROR_INVALID_DIMENSION          : printf("Error: VX_ERROR_INVALID_DIMENSION  Indicates that the supplied parameter is too big or too small in dimension. \n"); break;
                case    VX_ERROR_INVALID_FORMAT             : printf("Error: VX_ERROR_INVALID_FORMAT     Indicates that the supplied parameter is in an invalid format. \n"); break;
                case    VX_ERROR_INVALID_LINK               : printf("Error: VX_ERROR_INVALID_LINK       Indicates that the link is not possible as specified. The parameters are incompatible. \n"); break;
                case    VX_ERROR_INVALID_REFERENCE          : printf("Error: VX_ERROR_INVALID_REFERENCE  Indicates that the reference provided is not valid. \n"); break;
                case    VX_ERROR_INVALID_MODULE             : printf("Error: VX_ERROR_INVALID_MODULE     This is returned from ref vxLoadKernels when the module does not contain the entry point. \n"); break;
                case    VX_ERROR_INVALID_PARAMETERS         : printf("Error: VX_ERROR_INVALID_PARAMETERS Indicates that the supplied parameter information does not match the kernel contract. \n"); break;
                case    VX_ERROR_OPTIMIZED_AWAY             : printf("Error: VX_ERROR_OPTIMIZED_AWAY     Indicates that the object refered to has been optimized out of existence. \n"); break;
                case    VX_ERROR_NO_MEMORY                  : printf("Error: VX_ERROR_NO_MEMORY          Indicates that an internal or implicit allocation failed. Typically catastrophic. After detection, deconstruct the context. see vxVerifyGraph. \n"); break;
                case    VX_ERROR_NO_RESOURCES               : printf("Error: VX_ERROR_NO_RESOURCES       Indicates that an internal or implicit resource can not be acquired (not memory). This is typically catastrophic. After detection, deconstruct the context. see vxVerifyGraph. \n"); break;
                case    VX_ERROR_NOT_COMPATIBLE             : printf("Error: VX_ERROR_NOT_COMPATIBLE     Indicates that the attempt to link two parameters together failed due to type incompatibilty. \n"); break;
                case    VX_ERROR_NOT_ALLOCATED              : printf("Error: VX_ERROR_NOT_ALLOCATED      Indicates to the system that the parameter must be allocated by the system.  \n"); break;
                case    VX_ERROR_NOT_SUFFICIENT             : printf("Error: VX_ERROR_NOT_SUFFICIENT     Indicates that the given graph has failed verification due to an insufficient number of required parameters, which cannot be automatically created. Typically this indicates required atomic parameters. see vxVerifyGraph. \n"); break;
                case    VX_ERROR_NOT_SUPPORTED              : printf("Error: VX_ERROR_NOT_SUPPORTED      Indicates that the requested set of parameters produce a configuration that cannot be supported. Refer to the supplied documentation on the configured kernels. see vx_kernel_e. \n"); break;
                case    VX_ERROR_NOT_IMPLEMENTED            : printf("Error: VX_ERROR_NOT_IMPLEMENTED    Indicates that the requested kernel is missing. see vx_kernel_e vxGetKernelByName. \n"); break;
                case    VX_FAILURE                          : printf("Error: VX_FAILURE                  Indicates a generic error code, used when no other describes the error. \n"); break;
                case    VX_SUCCESS                          : printf("       VX_SUCCESS                  No error. \n"); break;
        }
}

Hi,
I have almost the same “Hello World” problem.
I’m writing a sample app that makes a vx_image and writes it to a file with nvxio.
My sample code is:

std::string name = "frame.jpg";
auto render = nvxio::createImageRender(context, name, width, height, VX_DF_IMAGE_RGBX);

the problem is that createImageRender is constantly returns null and I can’t manage to make it work.
I’ve initialized the context and the code

std::cout << "converting frame status: " << vxuColorConvert(context, image, image_rgbx) << std::endl;

shows status = 0 i.e. VX_SUCCESS.
nvxio::createImageRender is the only nvxio function in my app. I don’t use nvxio::Application etc.

How may I check the reason why the function nvxio::createImageRender() does not work?

It’s probably the same cause as this thread: https://devtalk.nvidia.com/default/topic/965838/jetson-tx1/unable-to-install-package-libvisionworks-nvxi-jetpack-l4t-2-1-1-32-bit-via-jetpack-2-3-/

No, actually I’m trying this on my Desktop host. nvxio is installed there and I’m able to link against it.

If this is a host issue, then the GPU Accelerated Libraries board is more appropriate, but I see that you’ve already posted there. You may wish to bump that thread as there is likely more VisionWorks expertise there than here.