From 5c969d1972f6e90ede402b0cdaf108396e841e6c Mon Sep 17 00:00:00 2001 From: Rostislav Vasilikhin Date: Thu, 1 Sep 2016 14:34:34 +0300 Subject: [PATCH 01/10] interoperability OpenVX samples added --- samples/CMakeLists.txt | 4 + samples/openvx/CMakeLists.txt | 36 +++ samples/openvx/no_wrappers.cpp | 382 ++++++++++++++++++++++++++++++ samples/openvx/wrappers.cpp | 216 +++++++++++++++++ samples/openvx/wrappers_video.cpp | 253 ++++++++++++++++++++ 5 files changed, 891 insertions(+) create mode 100644 samples/openvx/CMakeLists.txt create mode 100644 samples/openvx/no_wrappers.cpp create mode 100644 samples/openvx/wrappers.cpp create mode 100644 samples/openvx/wrappers_video.cpp diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index 70b85eecd3..b1f98e969d 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -22,6 +22,10 @@ if((NOT ANDROID) AND HAVE_OPENGL) add_subdirectory(opengl) endif() +if(HAVE_OPENVX) + add_subdirectory(openvx) +endif() + if(UNIX AND NOT ANDROID AND (HAVE_VA OR HAVE_VA_INTEL)) add_subdirectory(va_intel) endif() diff --git a/samples/openvx/CMakeLists.txt b/samples/openvx/CMakeLists.txt new file mode 100644 index 0000000000..3f891f2794 --- /dev/null +++ b/samples/openvx/CMakeLists.txt @@ -0,0 +1,36 @@ +cmake_minimum_required(VERSION 2.8.9) + +set(OPENCV_OPENVX_SAMPLE_REQUIRED_DEPS opencv_core opencv_imgproc opencv_imgcodecs opencv_videoio opencv_highgui) + +ocv_check_dependencies(${OPENCV_OPENVX_SAMPLE_REQUIRED_DEPS}) + +if(BUILD_EXAMPLES AND OCV_DEPENDENCIES_FOUND) + set(group "openvx") + set(name_wrapped "interop") + set(name_orig "interop_orig") + set(name_video "interop_video") + + project("${group}_sample") + + ocv_include_modules_recurse(${OPENCV_OPENVX_SAMPLE_REQUIRED_DEPS}) + + add_definitions(-DIVX_USE_OPENCV) + + file(GLOB srcs_wrapped wrappers.cpp *.hpp) + file(GLOB srcs_orig no_wrappers.cpp *.hpp) + file(GLOB srcs_video wrappers_video.cpp *.hpp) + + MACRO(OPENVX_DEFINE_SAMPLE name srcs) + set(target "example_${group}_${name}") + add_executable(${target} ${srcs}) + ocv_target_link_libraries(${target} ${OPENCV_LINKER_LIBS} ${OPENCV_OPENVX_SAMPLE_REQUIRED_DEPS} ${OPENVX_LIBRARIES}) + if(ENABLE_SOLUTION_FOLDERS) + set_target_properties(${target} PROPERTIES FOLDER "samples//${group}") + endif() + ENDMACRO() + + OPENVX_DEFINE_SAMPLE(${name_wrapped} ${srcs_wrapped}) + OPENVX_DEFINE_SAMPLE(${name_orig} ${srcs_orig}) + OPENVX_DEFINE_SAMPLE(${name_video} ${srcs_video}) + +endif() diff --git a/samples/openvx/no_wrappers.cpp b/samples/openvx/no_wrappers.cpp new file mode 100644 index 0000000000..c15367a526 --- /dev/null +++ b/samples/openvx/no_wrappers.cpp @@ -0,0 +1,382 @@ +#include +#include + +//OpenVX includes +#include + +//OpenCV includes +#include "opencv2/core.hpp" +#include "opencv2/imgproc.hpp" +#include "opencv2/imgcodecs.hpp" +#include "opencv2/highgui.hpp" + +#ifndef VX_VERSION_1_1 +const vx_enum VX_IMAGE_FORMAT = VX_IMAGE_ATTRIBUTE_FORMAT; +const vx_enum VX_IMAGE_WIDTH = VX_IMAGE_ATTRIBUTE_WIDTH; +const vx_enum VX_IMAGE_HEIGHT = VX_IMAGE_ATTRIBUTE_HEIGHT; +const vx_enum VX_MEMORY_TYPE_HOST = VX_IMPORT_TYPE_HOST; +const vx_enum VX_MEMORY_TYPE_NONE = VX_IMPORT_TYPE_NONE; +const vx_enum VX_THRESHOLD_THRESHOLD_VALUE = VX_THRESHOLD_ATTRIBUTE_THRESHOLD_VALUE; +const vx_enum VX_THRESHOLD_THRESHOLD_LOWER = VX_THRESHOLD_ATTRIBUTE_THRESHOLD_LOWER; +const vx_enum VX_THRESHOLD_THRESHOLD_UPPER = VX_THRESHOLD_ATTRIBUTE_THRESHOLD_UPPER; +typedef uintptr_t vx_map_id; +#endif + +enum UserMemoryMode +{ + COPY, MAP_TO_VX +}; + +vx_image convertCvMatToVxImage(vx_context context, cv::Mat image, bool toCopy) +{ + if (!(!image.empty() && image.dims <= 2 && image.channels() == 1)) + throw std::runtime_error("Invalid format"); + + vx_uint32 width = image.cols; + vx_uint32 height = image.rows; + + vx_df_image color; + switch (image.depth()) + { + case CV_8U: + color = VX_DF_IMAGE_U8; + break; + case CV_16U: + color = VX_DF_IMAGE_U16; + break; + case CV_16S: + color = VX_DF_IMAGE_S16; + break; + case CV_32S: + color = VX_DF_IMAGE_S32; + break; + default: + throw std::runtime_error("Invalid format"); + break; + } + + vx_imagepatch_addressing_t addr; + addr.dim_x = width; + addr.dim_y = height; + addr.stride_x = (vx_uint32)image.elemSize(); + addr.stride_y = (vx_uint32)image.step.p[0]; + vx_uint8* ovxData = image.data; + + vx_image ovxImage; + if (toCopy) + { + ovxImage = vxCreateImage(context, width, height, color); + if (vxGetStatus((vx_reference)ovxImage) != VX_SUCCESS) + throw std::runtime_error("Failed to create image"); + vx_rectangle_t rect; + + vx_status status = vxGetValidRegionImage(ovxImage, &rect); + if (status != VX_SUCCESS) + throw std::runtime_error("Failed to get valid region"); + +#ifdef VX_VERSION_1_1 + status = vxCopyImagePatch(ovxImage, &rect, 0, &addr, ovxData, VX_WRITE_ONLY, VX_MEMORY_TYPE_HOST); + if (status != VX_SUCCESS) + throw std::runtime_error("Failed to copy image patch"); +#else + status = vxAccessImagePatch(ovxImage, &rect, 0, &addr, (void**)&ovxData, VX_WRITE_ONLY); + if (status != VX_SUCCESS) + throw std::runtime_error("Failed to access image patch"); + status = vxCommitImagePatch(ovxImage, &rect, 0, &addr, ovxData); + if (status != VX_SUCCESS) + throw std::runtime_error("Failed to commit image patch"); +#endif + } + else + { +#ifdef VX_VERSION_1_1 + ovxImage = vxCreateImageFromHandle(context, color, &addr, (void*const*)&ovxData, VX_MEMORY_TYPE_HOST); +#else + ovxImage = vxCreateImageFromHandle(context, color, &addr, (void**)&ovxData, VX_MEMORY_TYPE_HOST); +#endif + if (vxGetStatus((vx_reference)ovxImage) != VX_SUCCESS) + throw std::runtime_error("Failed to create image from handle"); + } + + return ovxImage; +} + + +cv::Mat copyVxImageToCvMat(vx_image ovxImage) +{ + vx_status status; + vx_df_image df_image = 0; + vx_uint32 width, height; + status = vxQueryImage(ovxImage, VX_IMAGE_FORMAT, &df_image, sizeof(vx_df_image)); + if (status != VX_SUCCESS) + throw std::runtime_error("Failed to query image"); + status = vxQueryImage(ovxImage, VX_IMAGE_WIDTH, &width, sizeof(vx_uint32)); + if (status != VX_SUCCESS) + throw std::runtime_error("Failed to query image"); + status = vxQueryImage(ovxImage, VX_IMAGE_HEIGHT, &height, sizeof(vx_uint32)); + if (status != VX_SUCCESS) + throw std::runtime_error("Failed to query image"); + + if (!(width > 0 && height > 0)) throw std::runtime_error("Invalid format"); + + int depth; + switch (df_image) + { + case VX_DF_IMAGE_U8: + depth = CV_8U; + break; + case VX_DF_IMAGE_U16: + depth = CV_16U; + break; + case VX_DF_IMAGE_S16: + depth = CV_16S; + break; + case VX_DF_IMAGE_S32: + depth = CV_32S; + break; + default: + throw std::runtime_error("Invalid format"); + break; + } + + cv::Mat image(height, width, CV_MAKE_TYPE(depth, 1)); + + vx_rectangle_t rect; + rect.start_x = rect.start_y = 0; + rect.end_x = width; rect.end_y = height; + + vx_imagepatch_addressing_t addr; + addr.dim_x = width; + addr.dim_y = height; + addr.stride_x = (vx_uint32)image.elemSize(); + addr.stride_y = (vx_uint32)image.step.p[0]; + vx_uint8* matData = image.data; + +#ifdef VX_VERSION_1_1 + status = vxCopyImagePatch(ovxImage, &rect, 0, &addr, matData, VX_READ_ONLY, VX_MEMORY_TYPE_HOST); + if (status != VX_SUCCESS) + throw std::runtime_error("Failed to copy image patch"); +#else + status = vxAccessImagePatch(ovxImage, &rect, 0, &addr, (void**)&matData, VX_READ_ONLY); + if (status != VX_SUCCESS) + throw std::runtime_error("Failed to access image patch"); + status = vxCommitImagePatch(ovxImage, &rect, 0, &addr, matData); + if (status != VX_SUCCESS) + throw std::runtime_error("Failed to commit image patch"); +#endif + + return image; +} + + +void swapVxImage(vx_image ovxImage) +{ +#ifdef VX_VERSION_1_1 + vx_status status; + vx_memory_type_e memType; + status = vxQueryImage(ovxImage, VX_IMAGE_MEMORY_TYPE, &memType, sizeof(vx_memory_type_e)); + if (status != VX_SUCCESS) + throw std::runtime_error("Failed to query image"); + if (memType == VX_MEMORY_TYPE_NONE) + { + //was created by copying user data + throw std::runtime_error("Image wasn't created from user handle"); + } + else + { + //was created from user handle + status = vxSwapImageHandle(ovxImage, NULL, NULL, 0); + if (status != VX_SUCCESS) + throw std::runtime_error("Failed to swap image handle"); + } +#else + //not supported until OpenVX 1.1 + (void) ovxImage; +#endif +} + + +vx_status createProcessingGraph(vx_image inputImage, vx_image outputImage, vx_graph& graph) +{ + vx_status status; + vx_context context = vxGetContext((vx_reference)inputImage); + status = vxGetStatus((vx_reference)context); + if(status != VX_SUCCESS) return status; + + graph = vxCreateGraph(context); + status = vxGetStatus((vx_reference)graph); + if (status != VX_SUCCESS) return status; + + vx_uint32 width, height; + status = vxQueryImage(inputImage, VX_IMAGE_WIDTH, &width, sizeof(vx_uint32)); + if (status != VX_SUCCESS) return status; + status = vxQueryImage(inputImage, VX_IMAGE_HEIGHT, &height, sizeof(vx_uint32)); + if (status != VX_SUCCESS) return status; + + // Intermediate images + vx_image + smoothed = vxCreateVirtualImage(graph, 0, 0, VX_DF_IMAGE_VIRT), + cannied = vxCreateVirtualImage(graph, 0, 0, VX_DF_IMAGE_VIRT), + halfImg = vxCreateImage(context, width, height, VX_DF_IMAGE_U8), + halfCanny = vxCreateImage(context, width, height, VX_DF_IMAGE_U8); + + vx_image virtualImages[] = {smoothed, cannied, halfImg, halfCanny}; + for(size_t i = 0; i < sizeof(virtualImages)/sizeof(vx_image); i++) + { + status = vxGetStatus((vx_reference)virtualImages[i]); + if (status != VX_SUCCESS) return status; + } + + // Constants + vx_uint32 threshValue = 50; + vx_threshold thresh = vxCreateThreshold(context, VX_THRESHOLD_TYPE_BINARY, VX_TYPE_UINT8); + vxSetThresholdAttribute(thresh, VX_THRESHOLD_THRESHOLD_VALUE, + &threshValue, sizeof(threshValue)); + + vx_uint32 threshCannyMin = 127; + vx_uint32 threshCannyMax = 192; + vx_threshold threshCanny = vxCreateThreshold(context, VX_THRESHOLD_TYPE_RANGE, VX_TYPE_UINT8); + vxSetThresholdAttribute(threshCanny, VX_THRESHOLD_THRESHOLD_LOWER, &threshCannyMin, + sizeof(threshCannyMin)); + vxSetThresholdAttribute(threshCanny, VX_THRESHOLD_THRESHOLD_UPPER, &threshCannyMax, + sizeof(threshCannyMax)); + vx_float32 alphaValue = 0.5; + vx_scalar alpha = vxCreateScalar(context, VX_TYPE_FLOAT32, &alphaValue); + + // Sequence of meaningless image operations + vx_node nodes[] = { + vxGaussian3x3Node(graph, inputImage, smoothed), + vxCannyEdgeDetectorNode(graph, smoothed, threshCanny, 3, VX_NORM_L2, cannied), + vxAccumulateWeightedImageNode(graph, inputImage, alpha, halfImg), + vxAccumulateWeightedImageNode(graph, cannied, alpha, halfCanny), + vxAddNode(graph, halfImg, halfCanny, VX_CONVERT_POLICY_SATURATE, outputImage) + }; + + for (size_t i = 0; i < sizeof(nodes) / sizeof(vx_node); i++) + { + status = vxGetStatus((vx_reference)nodes[i]); + if (status != VX_SUCCESS) return status; + } + + status = vxVerifyGraph(graph); + return status; +} + + +int ovxDemo(std::string inputPath, UserMemoryMode mode) +{ + cv::Mat image = cv::imread(inputPath, cv::IMREAD_GRAYSCALE); + if (image.empty()) return -1; + + //check image format + if (image.depth() != CV_8U || image.channels() != 1) return -1; + + vx_status status; + vx_context context = vxCreateContext(); + status = vxGetStatus((vx_reference)context); + if (status != VX_SUCCESS) return status; + + //put user data from cv::Mat to vx_image + vx_image ovxImage; + ovxImage = convertCvMatToVxImage(context, image, mode == COPY); + + vx_uint32 width = image.cols, height = image.rows; + + vx_image ovxResult; + cv::Mat output; + if (mode == COPY) + { + //we will copy data from vx_image to cv::Mat + ovxResult = vxCreateImage(context, width, height, VX_DF_IMAGE_U8); + if (vxGetStatus((vx_reference)ovxResult) != VX_SUCCESS) + throw std::runtime_error("Failed to create image"); + } + else + { + //create vx_image based on user data, no copying required + output = cv::Mat(height, width, CV_8U, cv::Scalar(0)); + ovxResult = convertCvMatToVxImage(context, output, false); + } + + vx_graph graph; + status = createProcessingGraph(ovxImage, ovxResult, graph); + if (status != VX_SUCCESS) return status; + + // Graph execution + status = vxProcessGraph(graph); + if (status != VX_SUCCESS) return status; + + //getting resulting image in cv::Mat + if (mode == COPY) + { + output = copyVxImageToCvMat(ovxResult); + } + else + { + //we should take user memory back from vx_image before using it (even before reading) + swapVxImage(ovxResult); + } + + //here output goes + cv::imshow("processing result", output); + cv::waitKey(0); + + //we need to take user memory back before releasing the image + if (mode == MAP_TO_VX) + swapVxImage(ovxImage); + + cv::destroyAllWindows(); + + status = vxReleaseContext(&context); + return status; +} + + +int main(int argc, char *argv[]) +{ + const std::string keys = + "{help h usage ? | | }" + "{image | | image to be processed}" + "{mode | copy | user memory interaction mode: \n" + "copy: create VX images and copy data to/from them\n" + "map_to_vx: use handles to user-allocated memory}" + ; + + cv::CommandLineParser parser(argc, argv, keys); + parser.about("OpenVX interoperability sample demonstrating standard OpenVX API." + "The application loads an image, processes it with OpenVX graph and outputs result in a window"); + if (parser.has("help")) + { + parser.printMessage(); + return 0; + } + std::string imgPath = parser.get("image"); + std::string modeString = parser.get("mode"); + UserMemoryMode mode; + if(modeString == "copy") + { + mode = COPY; + } + else if(modeString == "map_to_vx") + { + mode = MAP_TO_VX; + } + else if(modeString == "map_from_vx") + { + std::cerr << modeString << " is not implemented in this sample" << std::endl; + return -1; + } + else + { + std::cerr << modeString << ": unknown memory mode" << std::endl; + return -1; + } + + if (!parser.check()) + { + parser.printErrors(); + return -1; + } + + return ovxDemo(imgPath, mode); +} diff --git a/samples/openvx/wrappers.cpp b/samples/openvx/wrappers.cpp new file mode 100644 index 0000000000..5dd7da17c7 --- /dev/null +++ b/samples/openvx/wrappers.cpp @@ -0,0 +1,216 @@ +#include +#include + +//wrappers +#include "ivx.hpp" + +//OpenCV includes +#include "opencv2/core.hpp" +#include "opencv2/imgproc.hpp" +#include "opencv2/imgcodecs.hpp" +#include "opencv2/highgui.hpp" + +enum UserMemoryMode +{ + COPY, MAP_TO_VX, MAP_FROM_VX +}; + +ivx::Graph createProcessingGraph(ivx::Image& inputImage, ivx::Image& outputImage) +{ + using namespace ivx; + + Context context = inputImage.getContext(); + + Graph graph = Graph::create(context); + + vx_uint32 width = inputImage.width(); + vx_uint32 height = inputImage.height(); + + // Intermediate images + Image + smoothed = Image::createVirtual(graph), + cannied = Image::createVirtual(graph), + halfImg = Image::create(context, width, height, VX_DF_IMAGE_U8), + halfCanny = Image::create(context, width, height, VX_DF_IMAGE_U8); + + // Constants + vx_uint32 threshCannyMin = 127; + vx_uint32 threshCannyMax = 192; + Threshold threshCanny = Threshold::createRange(context, VX_TYPE_UINT8, threshCannyMin, threshCannyMax); + + ivx::Scalar alpha = ivx::Scalar::create(context, 0.5); + + // Sequence of some image operations + // Node can also be added in function-like style + nodes::gaussian3x3(graph, inputImage, smoothed); + Node::create(graph, VX_KERNEL_CANNY_EDGE_DETECTOR, smoothed, threshCanny, + ivx::Scalar::create(context, 3), + ivx::Scalar::create(context, VX_NORM_L2), cannied); + Node::create(graph, VX_KERNEL_ACCUMULATE_WEIGHTED, inputImage, alpha, halfImg); + Node::create(graph, VX_KERNEL_ACCUMULATE_WEIGHTED, cannied, alpha, halfCanny); + Node::create(graph, VX_KERNEL_ADD, halfImg, halfCanny, + ivx::Scalar::create(context, VX_CONVERT_POLICY_SATURATE), outputImage); + + graph.verify(); + + return graph; +} + + +int ovxDemo(std::string inputPath, UserMemoryMode mode) +{ + using namespace cv; + using namespace ivx; + + Mat image = imread(inputPath, IMREAD_GRAYSCALE); + if (image.empty()) return -1; + + //check image format + if (image.depth() != CV_8U || image.channels() != 1) return -1; + + try + { + Context context = Context::create(); + //put user data from cv::Mat to vx_image + vx_df_image color = Image::matTypeToFormat(image.type()); + vx_uint32 width = image.cols, height = image.rows; + Image ivxImage; + if (mode == COPY) + { + ivxImage = Image::create(context, width, height, color); + ivxImage.copyFrom(0, image); + } + else + { + vx_imagepatch_addressing_t addressing = Image::createAddressing(image); + const std::vector addrs(1, addressing); + const std::vector ptrs(1, image.data); + ivxImage = Image::createFromHandle(context, color, addrs, ptrs); + } + + Image ivxResult; + Image::Patch resultPatch; + Mat output; + if (mode == COPY || mode == MAP_FROM_VX) + { + //we will copy or map data from vx_image to cv::Mat + ivxResult = ivx::Image::create(context, width, height, VX_DF_IMAGE_U8); + } + else // if (mode == MAP_TO_VX) + { + //create vx_image based on user data, no copying required + output = cv::Mat(height, width, CV_8U, cv::Scalar(0)); + vx_imagepatch_addressing_t addressing = Image::createAddressing(output); + const std::vector addrs(1, addressing); + const std::vector ptrs(1, output.data); + ivxResult = Image::createFromHandle(context, Image::matTypeToFormat(CV_8U), addrs, ptrs); + } + + Graph graph = createProcessingGraph(ivxImage, ivxResult); + + // Graph execution + graph.process(); + + //getting resulting image in cv::Mat + if (mode == COPY) + { + ivxResult.copyTo(0, output); + } + else if (mode == MAP_FROM_VX) + { + //create cv::Mat based on vx_image mapped data + resultPatch.map(ivxResult, 0, ivxResult.getValidRegion()); + //generally this is very bad idea! + //but in our case unmap() won't happen until output is in use + output = resultPatch.getMat(); + } + else // if (mode == MAP_TO_VX) + { +#ifdef VX_VERSION_1_1 + //we should take user memory back from vx_image before using it (even before reading) + ivxResult.swapHandle(); +#endif + } + + //here output goes + cv::imshow("processing result", output); + cv::waitKey(0); + + cv::destroyAllWindows(); + +#ifdef VX_VERSION_1_1 + if (mode != COPY) + { + //we should take user memory back before release + //(it's not done automatically according to standard) + ivxImage.swapHandle(); + if (mode == MAP_TO_VX) ivxResult.swapHandle(); + } +#endif + + //the line is unnecessary since unmapping is done on destruction of patch + //resultPatch.unmap(); + } + catch (const ivx::RuntimeError& e) + { + std::cerr << "Error: code = " << e.status() << ", message = " << e.what() << std::endl; + return e.status(); + } + catch (const ivx::WrapperError& e) + { + std::cerr << "Error: message = " << e.what() << std::endl; + return -1; + } + + return 0; +} + + +int main(int argc, char *argv[]) +{ + const std::string keys = + "{help h usage ? | | }" + "{image | | image to be processed}" + "{mode | copy | user memory interaction mode: \n" + "copy: create VX images and copy data to/from them\n" + "map_to_vx: use handles to user-allocated memory\n" + "map_from_vx: map resulting VX image to user memory}" + ; + + cv::CommandLineParser parser(argc, argv, keys); + parser.about("OpenVX interoperability sample demonstrating OpenVX wrappers usage." + "The application loads an image, processes it with OpenVX graph and outputs result in a window"); + if (parser.has("help")) + { + parser.printMessage(); + return 0; + } + std::string imgPath = parser.get("image"); + std::string modeString = parser.get("mode"); + UserMemoryMode mode; + if(modeString == "copy") + { + mode = COPY; + } + else if(modeString == "map_to_vx") + { + mode = MAP_TO_VX; + } + else if(modeString == "map_from_vx") + { + mode = MAP_FROM_VX; + } + else + { + std::cerr << modeString << ": unknown memory mode" << std::endl; + return -1; + } + + if (!parser.check()) + { + parser.printErrors(); + return -1; + } + + return ovxDemo(imgPath, mode); +} diff --git a/samples/openvx/wrappers_video.cpp b/samples/openvx/wrappers_video.cpp new file mode 100644 index 0000000000..df7be472db --- /dev/null +++ b/samples/openvx/wrappers_video.cpp @@ -0,0 +1,253 @@ +#include +#include + +//wrappers +#include "ivx.hpp" + +//OpenCV includes +#include "opencv2/core.hpp" +#include "opencv2/imgproc.hpp" +#include "opencv2/imgcodecs.hpp" +#include "opencv2/highgui.hpp" + +enum UserMemoryMode +{ + COPY, MAP_TO_VX, MAP_FROM_VX +}; + +ivx::Graph createProcessingGraph(ivx::Image& inputImage, ivx::Image& outputImage) +{ + using namespace ivx; + + Context context = inputImage.getContext(); + + Graph graph = Graph::create(context); + + vx_uint32 width = inputImage.width(); + vx_uint32 height = inputImage.height(); + + // Intermediate images + Image + yuv = Image::createVirtual(graph, 0, 0, VX_DF_IMAGE_YUV4), + gray = Image::createVirtual(graph), + smoothed = Image::createVirtual(graph), + cannied = Image::createVirtual(graph), + halfImg = Image::create(context, width, height, VX_DF_IMAGE_U8), + halfCanny = Image::create(context, width, height, VX_DF_IMAGE_U8); + + // Constants + vx_uint32 threshCannyMin = 127; + vx_uint32 threshCannyMax = 192; + Threshold threshCanny = Threshold::createRange(context, VX_TYPE_UINT8, threshCannyMin, threshCannyMax); + + ivx::Scalar alpha = ivx::Scalar::create(context, 0.5); + + // Sequence of some image operations + Node::create(graph, VX_KERNEL_COLOR_CONVERT, inputImage, yuv); + Node::create(graph, VX_KERNEL_CHANNEL_EXTRACT, yuv, + ivx::Scalar::create(context, VX_CHANNEL_Y), gray); + //node can also be added in function-like style + nodes::gaussian3x3(graph, gray, smoothed); + Node::create(graph, VX_KERNEL_CANNY_EDGE_DETECTOR, smoothed, threshCanny, + ivx::Scalar::create(context, 3), + ivx::Scalar::create(context, VX_NORM_L2), cannied); + Node::create(graph, VX_KERNEL_ACCUMULATE_WEIGHTED, gray, alpha, halfImg); + Node::create(graph, VX_KERNEL_ACCUMULATE_WEIGHTED, cannied, alpha, halfCanny); + Node::create(graph, VX_KERNEL_ADD, halfImg, halfCanny, + ivx::Scalar::create(context, VX_CONVERT_POLICY_SATURATE), outputImage); + + graph.verify(); + + return graph; +} + + +int ovxDemo(std::string inputPath, UserMemoryMode mode) +{ + using namespace cv; + using namespace ivx; + + Mat frame; + VideoCapture vc(inputPath); + if (!vc.isOpened()) + return -1; + + vc >> frame; + if (frame.empty()) return -1; + + //check frame format + if (frame.type() != CV_8UC3) return -1; + + try + { + Context context = Context::create(); + //put user data from cv::Mat to vx_image + vx_df_image color = Image::matTypeToFormat(frame.type()); + vx_uint32 width = frame.cols, height = frame.rows; + Image ivxImage; + if (mode == COPY) + { + ivxImage = Image::create(context, width, height, color); + } + else + { + vx_imagepatch_addressing_t addressing = Image::createAddressing(frame); + const std::vector addrs(1, addressing); + const std::vector ptrs(1, frame.data); + ivxImage = Image::createFromHandle(context, color, addrs, ptrs); + } + + Image ivxResult; + + Mat output; + if (mode == COPY || mode == MAP_FROM_VX) + { + //we will copy or map data from vx_image to cv::Mat + ivxResult = ivx::Image::create(context, width, height, VX_DF_IMAGE_U8); + } + else // if (mode == MAP_TO_VX) + { + //create vx_image based on user data, no copying required + output = cv::Mat(height, width, CV_8U, cv::Scalar(0)); + vx_imagepatch_addressing_t addressing = Image::createAddressing(output); + const std::vector addrs(1, addressing); + const std::vector ptrs(1, output.data); + ivxResult = Image::createFromHandle(context, Image::matTypeToFormat(CV_8U), addrs, ptrs); + } + + Graph graph = createProcessingGraph(ivxImage, ivxResult); + + std::vector ptrs; + + bool stop = false; + while (!stop) + { + if (mode == COPY) ivxImage.copyFrom(0, frame); + + // Graph execution + graph.process(); + + //getting resulting image in cv::Mat + Image::Patch resultPatch; + std::vector prevPtrs; + if (mode == COPY) + { + ivxResult.copyTo(0, output); + } + else if (mode == MAP_FROM_VX) + { + //create cv::Mat based on vx_image mapped data + resultPatch.map(ivxResult, 0, ivxResult.getValidRegion(), VX_READ_AND_WRITE); + //generally this is very bad idea! + //but in our case unmap() won't happen until output is in use + output = resultPatch.getMat(); + } + else // if(mode == MAP_TO_VX) + { +#ifdef VX_VERSION_1_1 + //we should take user memory back from vx_image before using it (even before reading) + ivxResult.swapHandle(ptrs, prevPtrs); +#endif + } + + //here output goes + imshow("press q to quit", output); + if ((char)waitKey(1) == 'q') stop = true; + +#ifdef VX_VERSION_1_1 + //restore handle + if (mode == MAP_TO_VX) + { + ivxResult.swapHandle(prevPtrs); + } +#endif + + //this line is unnecessary since unmapping is done on destruction of patch + //resultPatch.unmap(); + + //grab next frame + Mat temp = frame; + vc >> frame; + if (frame.empty()) stop = true; + if (mode != COPY && frame.data != temp.data) + { + //frame was reallocated, pointer to data changed + frame.copyTo(temp); + } + } + + destroyAllWindows(); + +#ifdef VX_VERSION_1_1 + if (mode != COPY) + { + //we should take user memory back before release + //(it's not done automatically according to standard) + ivxImage.swapHandle(); + if (mode == MAP_TO_VX) ivxResult.swapHandle(); + } +#endif + } + catch (const ivx::RuntimeError& e) + { + std::cerr << "Error: code = " << e.status() << ", message = " << e.what() << std::endl; + return e.status(); + } + catch (const ivx::WrapperError& e) + { + std::cerr << "Error: message = " << e.what() << std::endl; + return -1; + } + + return 0; +} + + +int main(int argc, char *argv[]) +{ + const std::string keys = + "{help h usage ? | | }" + "{video | | video file to be processed}" + "{mode | copy | user memory interaction mode: \n" + "copy: create VX images and copy data to/from them\n" + "map_to_vx: use handles to user-allocated memory\n" + "map_from_vx: map resulting VX image to user memory}" + ; + + cv::CommandLineParser parser(argc, argv, keys); + parser.about("OpenVX interoperability sample demonstrating OpenVX wrappers usage." + "The application opens a video and processes it with OpenVX graph while outputting result in a window"); + if (parser.has("help")) + { + parser.printMessage(); + return 0; + } + std::string videoPath = parser.get("video"); + std::string modeString = parser.get("mode"); + UserMemoryMode mode; + if(modeString == "copy") + { + mode = COPY; + } + else if(modeString == "map_to_vx") + { + mode = MAP_TO_VX; + } + else if(modeString == "map_from_vx") + { + mode = MAP_FROM_VX; + } + else + { + std::cerr << modeString << ": unknown memory mode" << std::endl; + return -1; + } + + if (!parser.check()) + { + parser.printErrors(); + return -1; + } + + return ovxDemo(videoPath, mode); +} From 9032a7ab8145c5907e2029fbb9319c7b5c2a376b Mon Sep 17 00:00:00 2001 From: Rostislav Vasilikhin Date: Thu, 17 Nov 2016 15:58:23 +0300 Subject: [PATCH 02/10] minor fixes in samples and ivx.hpp --- 3rdparty/openvx/include/ivx.hpp | 9 +++++++-- samples/openvx/no_wrappers.cpp | 16 ++++++---------- samples/openvx/wrappers.cpp | 20 ++++++++++---------- samples/openvx/wrappers_video.cpp | 29 ++++++++++++++--------------- 4 files changed, 37 insertions(+), 37 deletions(-) diff --git a/3rdparty/openvx/include/ivx.hpp b/3rdparty/openvx/include/ivx.hpp index c6602e4b99..eafac4c6dc 100644 --- a/3rdparty/openvx/include/ivx.hpp +++ b/3rdparty/openvx/include/ivx.hpp @@ -58,6 +58,11 @@ Details: TBD #ifndef IVX_USE_CXX98 #include + namespace ivx + { + using std::is_same; + using std::is_pointer; + } #else namespace ivx { @@ -1517,8 +1522,8 @@ static const vx_enum static Threshold createRange(vx_context c, vx_enum dataType, vx_int32 valLower, vx_int32 valUpper) { Threshold thr = create(c, VX_THRESHOLD_TYPE_RANGE, dataType); - IVX_CHECK_STATUS( vxSetThresholdAttribute(thr.ref, VX_THRESHOLD_THRESHOLD_LOWER, &val1, sizeof(val1)) ); - IVX_CHECK_STATUS( vxSetThresholdAttribute(thr.ref, VX_THRESHOLD_THRESHOLD_UPPER, &val2, sizeof(val2)) ); + IVX_CHECK_STATUS( vxSetThresholdAttribute(thr.ref, VX_THRESHOLD_THRESHOLD_LOWER, &valLower, sizeof(valLower)) ); + IVX_CHECK_STATUS( vxSetThresholdAttribute(thr.ref, VX_THRESHOLD_THRESHOLD_UPPER, &valUpper, sizeof(valUpper)) ); return thr; } diff --git a/samples/openvx/no_wrappers.cpp b/samples/openvx/no_wrappers.cpp index c15367a526..99a8ecab82 100644 --- a/samples/openvx/no_wrappers.cpp +++ b/samples/openvx/no_wrappers.cpp @@ -24,7 +24,7 @@ typedef uintptr_t vx_map_id; enum UserMemoryMode { - COPY, MAP_TO_VX + COPY, USER_MEM }; vx_image convertCvMatToVxImage(vx_context context, cv::Mat image, bool toCopy) @@ -89,11 +89,7 @@ vx_image convertCvMatToVxImage(vx_context context, cv::Mat image, bool toCopy) } else { -#ifdef VX_VERSION_1_1 - ovxImage = vxCreateImageFromHandle(context, color, &addr, (void*const*)&ovxData, VX_MEMORY_TYPE_HOST); -#else ovxImage = vxCreateImageFromHandle(context, color, &addr, (void**)&ovxData, VX_MEMORY_TYPE_HOST); -#endif if (vxGetStatus((vx_reference)ovxImage) != VX_SUCCESS) throw std::runtime_error("Failed to create image from handle"); } @@ -322,7 +318,7 @@ int ovxDemo(std::string inputPath, UserMemoryMode mode) cv::waitKey(0); //we need to take user memory back before releasing the image - if (mode == MAP_TO_VX) + if (mode == USER_MEM) swapVxImage(ovxImage); cv::destroyAllWindows(); @@ -339,7 +335,7 @@ int main(int argc, char *argv[]) "{image | | image to be processed}" "{mode | copy | user memory interaction mode: \n" "copy: create VX images and copy data to/from them\n" - "map_to_vx: use handles to user-allocated memory}" + "user_mem: use handles to user-allocated memory}" ; cv::CommandLineParser parser(argc, argv, keys); @@ -357,11 +353,11 @@ int main(int argc, char *argv[]) { mode = COPY; } - else if(modeString == "map_to_vx") + else if(modeString == "user_mem") { - mode = MAP_TO_VX; + mode = USER_MEM; } - else if(modeString == "map_from_vx") + else if(modeString == "map") { std::cerr << modeString << " is not implemented in this sample" << std::endl; return -1; diff --git a/samples/openvx/wrappers.cpp b/samples/openvx/wrappers.cpp index 5dd7da17c7..6655d3fd24 100644 --- a/samples/openvx/wrappers.cpp +++ b/samples/openvx/wrappers.cpp @@ -12,7 +12,7 @@ enum UserMemoryMode { - COPY, MAP_TO_VX, MAP_FROM_VX + COPY, USER_MEM, MAP }; ivx::Graph createProcessingGraph(ivx::Image& inputImage, ivx::Image& outputImage) @@ -91,7 +91,7 @@ int ovxDemo(std::string inputPath, UserMemoryMode mode) Image ivxResult; Image::Patch resultPatch; Mat output; - if (mode == COPY || mode == MAP_FROM_VX) + if (mode == COPY || mode == MAP) { //we will copy or map data from vx_image to cv::Mat ivxResult = ivx::Image::create(context, width, height, VX_DF_IMAGE_U8); @@ -116,7 +116,7 @@ int ovxDemo(std::string inputPath, UserMemoryMode mode) { ivxResult.copyTo(0, output); } - else if (mode == MAP_FROM_VX) + else if (mode == MAP) { //create cv::Mat based on vx_image mapped data resultPatch.map(ivxResult, 0, ivxResult.getValidRegion()); @@ -144,7 +144,7 @@ int ovxDemo(std::string inputPath, UserMemoryMode mode) //we should take user memory back before release //(it's not done automatically according to standard) ivxImage.swapHandle(); - if (mode == MAP_TO_VX) ivxResult.swapHandle(); + if (mode == USER_MEM) ivxResult.swapHandle(); } #endif @@ -173,8 +173,8 @@ int main(int argc, char *argv[]) "{image | | image to be processed}" "{mode | copy | user memory interaction mode: \n" "copy: create VX images and copy data to/from them\n" - "map_to_vx: use handles to user-allocated memory\n" - "map_from_vx: map resulting VX image to user memory}" + "user_mem: use handles to user-allocated memory\n" + "map: map resulting VX image to user memory}" ; cv::CommandLineParser parser(argc, argv, keys); @@ -192,13 +192,13 @@ int main(int argc, char *argv[]) { mode = COPY; } - else if(modeString == "map_to_vx") + else if(modeString == "user_mem") { - mode = MAP_TO_VX; + mode = USER_MEM; } - else if(modeString == "map_from_vx") + else if(modeString == "map") { - mode = MAP_FROM_VX; + mode = MAP; } else { diff --git a/samples/openvx/wrappers_video.cpp b/samples/openvx/wrappers_video.cpp index df7be472db..c24d8ceedb 100644 --- a/samples/openvx/wrappers_video.cpp +++ b/samples/openvx/wrappers_video.cpp @@ -12,7 +12,7 @@ enum UserMemoryMode { - COPY, MAP_TO_VX, MAP_FROM_VX + COPY, USER_MEM, MAP }; ivx::Graph createProcessingGraph(ivx::Image& inputImage, ivx::Image& outputImage) @@ -100,7 +100,7 @@ int ovxDemo(std::string inputPath, UserMemoryMode mode) Image ivxResult; Mat output; - if (mode == COPY || mode == MAP_FROM_VX) + if (mode == COPY || mode == MAP) { //we will copy or map data from vx_image to cv::Mat ivxResult = ivx::Image::create(context, width, height, VX_DF_IMAGE_U8); @@ -117,8 +117,6 @@ int ovxDemo(std::string inputPath, UserMemoryMode mode) Graph graph = createProcessingGraph(ivxImage, ivxResult); - std::vector ptrs; - bool stop = false; while (!stop) { @@ -129,12 +127,13 @@ int ovxDemo(std::string inputPath, UserMemoryMode mode) //getting resulting image in cv::Mat Image::Patch resultPatch; - std::vector prevPtrs; + std::vector ptrs; + std::vector prevPtrs(ivxResult.planes()); if (mode == COPY) { ivxResult.copyTo(0, output); } - else if (mode == MAP_FROM_VX) + else if (mode == MAP) { //create cv::Mat based on vx_image mapped data resultPatch.map(ivxResult, 0, ivxResult.getValidRegion(), VX_READ_AND_WRITE); @@ -156,9 +155,9 @@ int ovxDemo(std::string inputPath, UserMemoryMode mode) #ifdef VX_VERSION_1_1 //restore handle - if (mode == MAP_TO_VX) + if (mode == USER_MEM) { - ivxResult.swapHandle(prevPtrs); + ivxResult.swapHandle(prevPtrs, ptrs); } #endif @@ -184,7 +183,7 @@ int ovxDemo(std::string inputPath, UserMemoryMode mode) //we should take user memory back before release //(it's not done automatically according to standard) ivxImage.swapHandle(); - if (mode == MAP_TO_VX) ivxResult.swapHandle(); + if (mode == USER_MEM) ivxResult.swapHandle(); } #endif } @@ -210,8 +209,8 @@ int main(int argc, char *argv[]) "{video | | video file to be processed}" "{mode | copy | user memory interaction mode: \n" "copy: create VX images and copy data to/from them\n" - "map_to_vx: use handles to user-allocated memory\n" - "map_from_vx: map resulting VX image to user memory}" + "user_mem: use handles to user-allocated memory\n" + "map: map resulting VX image to user memory}" ; cv::CommandLineParser parser(argc, argv, keys); @@ -229,13 +228,13 @@ int main(int argc, char *argv[]) { mode = COPY; } - else if(modeString == "map_to_vx") + else if(modeString == "user_mem") { - mode = MAP_TO_VX; + mode = USER_MEM; } - else if(modeString == "map_from_vx") + else if(modeString == "map") { - mode = MAP_FROM_VX; + mode = MAP; } else { From e8d2aad978a1c22165c2d1f773ea8537db730b91 Mon Sep 17 00:00:00 2001 From: apavlenko Date: Thu, 17 Nov 2016 19:27:14 +0300 Subject: [PATCH 03/10] sugar for single plane images --- 3rdparty/openvx/include/ivx.hpp | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/3rdparty/openvx/include/ivx.hpp b/3rdparty/openvx/include/ivx.hpp index eafac4c6dc..abf266e6db 100644 --- a/3rdparty/openvx/include/ivx.hpp +++ b/3rdparty/openvx/include/ivx.hpp @@ -871,6 +871,10 @@ public: static Image createVirtual(vx_graph graph, vx_uint32 width = 0, vx_uint32 height = 0, vx_df_image format = VX_DF_IMAGE_VIRT) { return Image(vxCreateVirtualImage(graph, width, height, format)); } + /// vxCreateUniformImage() wrapper + static Image createUniform(vx_context context, vx_uint32 width, vx_uint32 height, vx_df_image format, const vx_pixel_value_t& value) + { return Image(vxCreateUniformImage(context, width, height, format, &value)); } + /// Planes number for the specified image format (fourcc) /// \return 0 for unknown formats static vx_size planes(vx_df_image format) @@ -954,6 +958,13 @@ public: #endif } + /// vxCreateImageFromHandle() wrapper for a single plane image + static Image createFromHandle(vx_context context, vx_df_image format,const vx_imagepatch_addressing_t& addr, void* ptr) + { + if(planes(format) != 1) throw WrapperError(std::string(__func__)+"(): not a single plane format"); + return Image(vxCreateImageFromHandle(context, format, &addr, &ptr, VX_MEMORY_TYPE_HOST)); + } + #ifdef VX_VERSION_1_1 /// vxSwapImageHandle() wrapper /// \param newPtrs keeps addresses of new image planes data, can be of image planes size or empty when new pointers are not provided @@ -973,6 +984,17 @@ public: num ) ); } + /// vxSwapImageHandle() wrapper for a single plane image + /// \param newPtr an address of new image data, can be zero when new pointer is not provided + /// \return the previuos address of image data + void* swapHandle(void* newPtr) + { + if(planes() != 1) throw WrapperError(std::string(__func__)+"(): not a single plane image"); + void* prevPtr = 0; + IVX_CHECK_STATUS( vxSwapImageHandle(ref, &newPtr, &prevPtr, 1) ); + return prevPtr; + } + /// vxSwapImageHandle() wrapper for the case when no new pointers provided and previous ones are not needed (retrive memory back) void swapHandle() { IVX_CHECK_STATUS( vxSwapImageHandle(ref, 0, 0, 0) ); } @@ -1251,6 +1273,14 @@ static const vx_enum //vx_rectangle_t r = getValidRegion(); copyFrom(planeIdx, createAddressing((vx_uint32)m.cols, (vx_uint32)m.rows, (vx_int32)m.elemSize(), (vx_int32)m.step), m.ptr()); } + + /* + static Image createFromHandle(vx_context context, const cv::Mat& mat) + { throw WrapperError(std::string(__func__)+"(): NYI"); } + + cv::Mat swapHandle(const cv::Mat& newMat) + { throw WrapperError(std::string(__func__)+"(): NYI"); } + */ #endif //IVX_USE_OPENCV struct Patch; From 2c63d2bd729d3272fd64cb6eaf32d708a6df826c Mon Sep 17 00:00:00 2001 From: Rostislav Vasilikhin Date: Thu, 17 Nov 2016 19:42:58 +0300 Subject: [PATCH 04/10] changed image creation from handle --- samples/openvx/wrappers.cpp | 11 +++-------- samples/openvx/wrappers_video.cpp | 11 +++-------- 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/samples/openvx/wrappers.cpp b/samples/openvx/wrappers.cpp index 6655d3fd24..da75857f5c 100644 --- a/samples/openvx/wrappers.cpp +++ b/samples/openvx/wrappers.cpp @@ -82,10 +82,7 @@ int ovxDemo(std::string inputPath, UserMemoryMode mode) } else { - vx_imagepatch_addressing_t addressing = Image::createAddressing(image); - const std::vector addrs(1, addressing); - const std::vector ptrs(1, image.data); - ivxImage = Image::createFromHandle(context, color, addrs, ptrs); + ivxImage = Image::createFromHandle(context, color, Image::createAddressing(image), image.data); } Image ivxResult; @@ -100,10 +97,8 @@ int ovxDemo(std::string inputPath, UserMemoryMode mode) { //create vx_image based on user data, no copying required output = cv::Mat(height, width, CV_8U, cv::Scalar(0)); - vx_imagepatch_addressing_t addressing = Image::createAddressing(output); - const std::vector addrs(1, addressing); - const std::vector ptrs(1, output.data); - ivxResult = Image::createFromHandle(context, Image::matTypeToFormat(CV_8U), addrs, ptrs); + ivxResult = Image::createFromHandle(context, Image::matTypeToFormat(CV_8U), + Image::createAddressing(output), output.data); } Graph graph = createProcessingGraph(ivxImage, ivxResult); diff --git a/samples/openvx/wrappers_video.cpp b/samples/openvx/wrappers_video.cpp index c24d8ceedb..d08a845979 100644 --- a/samples/openvx/wrappers_video.cpp +++ b/samples/openvx/wrappers_video.cpp @@ -91,10 +91,7 @@ int ovxDemo(std::string inputPath, UserMemoryMode mode) } else { - vx_imagepatch_addressing_t addressing = Image::createAddressing(frame); - const std::vector addrs(1, addressing); - const std::vector ptrs(1, frame.data); - ivxImage = Image::createFromHandle(context, color, addrs, ptrs); + ivxImage = Image::createFromHandle(context, color, Image::createAddressing(frame), frame.data); } Image ivxResult; @@ -109,10 +106,8 @@ int ovxDemo(std::string inputPath, UserMemoryMode mode) { //create vx_image based on user data, no copying required output = cv::Mat(height, width, CV_8U, cv::Scalar(0)); - vx_imagepatch_addressing_t addressing = Image::createAddressing(output); - const std::vector addrs(1, addressing); - const std::vector ptrs(1, output.data); - ivxResult = Image::createFromHandle(context, Image::matTypeToFormat(CV_8U), addrs, ptrs); + ivxResult = Image::createFromHandle(context, Image::matTypeToFormat(CV_8U), + Image::createAddressing(output), output.data); } Graph graph = createProcessingGraph(ivxImage, ivxResult); From 289d879d48d4e8cc8a60f89118558fb904ec1b79 Mon Sep 17 00:00:00 2001 From: Andrey Pavlenko Date: Fri, 18 Nov 2016 15:11:17 +0300 Subject: [PATCH 05/10] build fixes for openvx-1.0.1 and c++03 * fixing 1.0.1 * fixing build without c++11 --- 3rdparty/openvx/include/ivx.hpp | 12 +++++++++--- samples/openvx/wrappers.cpp | 3 +-- samples/openvx/wrappers_video.cpp | 3 +-- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/3rdparty/openvx/include/ivx.hpp b/3rdparty/openvx/include/ivx.hpp index abf266e6db..5162adf379 100644 --- a/3rdparty/openvx/include/ivx.hpp +++ b/3rdparty/openvx/include/ivx.hpp @@ -532,7 +532,6 @@ public: operator vx_reference() const { return castToReference(ref); } -#ifdef IVX_USE_CXX98 /// Getting a context that is kept in each OpenVX 'object' (call get()) template C get() const @@ -542,7 +541,8 @@ public: // vxGetContext doesn't increment ref count, let do it in wrapper c-tor return C(c, true); } -#else + +#ifndef IVX_USE_CXX98 /// Getting a context that is kept in each OpenVX 'object' template::value>::type> C getContext() const @@ -871,9 +871,15 @@ public: static Image createVirtual(vx_graph graph, vx_uint32 width = 0, vx_uint32 height = 0, vx_df_image format = VX_DF_IMAGE_VIRT) { return Image(vxCreateVirtualImage(graph, width, height, format)); } +#ifdef VX_VERSION_1_1 /// vxCreateUniformImage() wrapper static Image createUniform(vx_context context, vx_uint32 width, vx_uint32 height, vx_df_image format, const vx_pixel_value_t& value) { return Image(vxCreateUniformImage(context, width, height, format, &value)); } +#else + /// vxCreateUniformImage() wrapper + static Image createUniform(vx_context context, vx_uint32 width, vx_uint32 height, vx_df_image format, const void* value) + { return Image(vxCreateUniformImage(context, width, height, format, value)); } +#endif /// Planes number for the specified image format (fourcc) /// \return 0 for unknown formats @@ -962,7 +968,7 @@ public: static Image createFromHandle(vx_context context, vx_df_image format,const vx_imagepatch_addressing_t& addr, void* ptr) { if(planes(format) != 1) throw WrapperError(std::string(__func__)+"(): not a single plane format"); - return Image(vxCreateImageFromHandle(context, format, &addr, &ptr, VX_MEMORY_TYPE_HOST)); + return Image(vxCreateImageFromHandle(context, format, const_cast (&addr), &ptr, VX_MEMORY_TYPE_HOST)); } #ifdef VX_VERSION_1_1 diff --git a/samples/openvx/wrappers.cpp b/samples/openvx/wrappers.cpp index da75857f5c..32a1442c55 100644 --- a/samples/openvx/wrappers.cpp +++ b/samples/openvx/wrappers.cpp @@ -19,8 +19,7 @@ ivx::Graph createProcessingGraph(ivx::Image& inputImage, ivx::Image& outputImage { using namespace ivx; - Context context = inputImage.getContext(); - + Context context = inputImage.get(); Graph graph = Graph::create(context); vx_uint32 width = inputImage.width(); diff --git a/samples/openvx/wrappers_video.cpp b/samples/openvx/wrappers_video.cpp index d08a845979..35caa2844c 100644 --- a/samples/openvx/wrappers_video.cpp +++ b/samples/openvx/wrappers_video.cpp @@ -19,8 +19,7 @@ ivx::Graph createProcessingGraph(ivx::Image& inputImage, ivx::Image& outputImage { using namespace ivx; - Context context = inputImage.getContext(); - + Context context = inputImage.get(); Graph graph = Graph::create(context); vx_uint32 width = inputImage.width(); From d7db22019695cf4f31eea46ffdd12982b12b2356 Mon Sep 17 00:00:00 2001 From: Rostislav Vasilikhin Date: Fri, 18 Nov 2016 16:11:32 +0300 Subject: [PATCH 06/10] "no previous declaration" warnings fixed in samples --- samples/openvx/no_wrappers.cpp | 7 +++++++ samples/openvx/wrappers.cpp | 4 ++++ samples/openvx/wrappers_video.cpp | 4 ++++ 3 files changed, 15 insertions(+) diff --git a/samples/openvx/no_wrappers.cpp b/samples/openvx/no_wrappers.cpp index 99a8ecab82..7809f7b9ca 100644 --- a/samples/openvx/no_wrappers.cpp +++ b/samples/openvx/no_wrappers.cpp @@ -27,6 +27,13 @@ enum UserMemoryMode COPY, USER_MEM }; +vx_image convertCvMatToVxImage(vx_context context, cv::Mat image, bool toCopy); +cv::Mat copyVxImageToCvMat(vx_image ovxImage); +void swapVxImage(vx_image ovxImage); +vx_status createProcessingGraph(vx_image inputImage, vx_image outputImage, vx_graph& graph); +int ovxDemo(std::string inputPath, UserMemoryMode mode); + + vx_image convertCvMatToVxImage(vx_context context, cv::Mat image, bool toCopy) { if (!(!image.empty() && image.dims <= 2 && image.channels() == 1)) diff --git a/samples/openvx/wrappers.cpp b/samples/openvx/wrappers.cpp index 32a1442c55..b591862c10 100644 --- a/samples/openvx/wrappers.cpp +++ b/samples/openvx/wrappers.cpp @@ -15,6 +15,10 @@ enum UserMemoryMode COPY, USER_MEM, MAP }; +ivx::Graph createProcessingGraph(ivx::Image& inputImage, ivx::Image& outputImage); +int ovxDemo(std::string inputPath, UserMemoryMode mode); + + ivx::Graph createProcessingGraph(ivx::Image& inputImage, ivx::Image& outputImage) { using namespace ivx; diff --git a/samples/openvx/wrappers_video.cpp b/samples/openvx/wrappers_video.cpp index 35caa2844c..737f052b85 100644 --- a/samples/openvx/wrappers_video.cpp +++ b/samples/openvx/wrappers_video.cpp @@ -15,6 +15,10 @@ enum UserMemoryMode COPY, USER_MEM, MAP }; +ivx::Graph createProcessingGraph(ivx::Image& inputImage, ivx::Image& outputImage); +int ovxDemo(std::string inputPath, UserMemoryMode mode); + + ivx::Graph createProcessingGraph(ivx::Image& inputImage, ivx::Image& outputImage) { using namespace ivx; From bfecea489e63c5ab29be5666ac18de97aab1e23e Mon Sep 17 00:00:00 2001 From: Andrey Pavlenko Date: Fri, 18 Nov 2016 16:22:11 +0300 Subject: [PATCH 07/10] warnings in ivx.hpp fixed * fixing 1.0.1 * fixing build without c++11 * hiding warnings --- 3rdparty/openvx/include/ivx.hpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/3rdparty/openvx/include/ivx.hpp b/3rdparty/openvx/include/ivx.hpp index 5162adf379..6dc417051d 100644 --- a/3rdparty/openvx/include/ivx.hpp +++ b/3rdparty/openvx/include/ivx.hpp @@ -89,8 +89,8 @@ class RuntimeError : public std::runtime_error { public: /// Constructor - explicit RuntimeError(vx_status status, const std::string& msg = "") - : runtime_error(msg), _status(status) + explicit RuntimeError(vx_status st, const std::string& msg = "") + : runtime_error(msg), _status(st) {} /// OpenVX error code @@ -142,7 +142,7 @@ template using EnumToType_t = typename EnumToType::type; #endif /// Gets size in bytes for the provided OpenVX type enum -vx_size enumToTypeSize(vx_enum type) +inline vx_size enumToTypeSize(vx_enum type) { switch (type) { @@ -1314,16 +1314,16 @@ public: { return _mapId; } #else /// reference to vx_rectangle_t for the current mapping - const vx_rectangle_t& rect() const + const vx_rectangle_t& rectangle() const { return _rect; } /// Image plane index for the current mapping - vx_uint32 planeIdx() const + vx_uint32 planeIndex() const { return _planeIdx; } #endif // VX_VERSION_1_1 /// vx_image for the current mapping - vx_image img() const + vx_image image() const { return _img; } /// where this patch is mapped @@ -1393,6 +1393,7 @@ public: IVX_CHECK_STATUS(vxMapImagePatch(img, &rect, planeIdx, &_mapId, &_addr, &_data, usage, _memType, flags) ); #else IVX_CHECK_STATUS(vxAccessImagePatch(img, &rect, planeIdx, &_addr, &_data, usage)); + (void)flags; _rect = rect; _planeIdx = planeIdx; #endif @@ -1565,8 +1566,8 @@ static const vx_enum /// vxQueryThreshold() wrapper template - void query(vx_enum att, T& value) const - { IVX_CHECK_STATUS( vxQueryThreshold(ref, att, &value, sizeof(value)) ); } + void query(vx_enum att, T& val) const + { IVX_CHECK_STATUS( vxQueryThreshold(ref, att, &value, sizeof(val)) ); } /// vxQueryThreshold(VX_THRESHOLD_TYPE) wrapper vx_enum type() const From fa8add8686976d7f006bd10a8e5624f1d692c62f Mon Sep 17 00:00:00 2001 From: Rostislav Vasilikhin Date: Mon, 21 Nov 2016 10:50:29 +0300 Subject: [PATCH 08/10] compilation fixed for C++98 --- 3rdparty/openvx/include/ivx.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/3rdparty/openvx/include/ivx.hpp b/3rdparty/openvx/include/ivx.hpp index 6dc417051d..cd36e071c7 100644 --- a/3rdparty/openvx/include/ivx.hpp +++ b/3rdparty/openvx/include/ivx.hpp @@ -410,7 +410,6 @@ public: { return ref != 0; } #endif -#ifdef IVX_USE_CXX98 /// Getting a context that is kept in each OpenVX 'object' (call get()) template C get() const @@ -420,7 +419,8 @@ public: // vxGetContext doesn't increment ref count, let do it in wrapper c-tor return C(c, true); } -#else + +#ifndef IVX_USE_CXX98 /// Getting a context that is kept in each OpenVX 'object' template::value>::type> C getContext() const @@ -1567,7 +1567,7 @@ static const vx_enum /// vxQueryThreshold() wrapper template void query(vx_enum att, T& val) const - { IVX_CHECK_STATUS( vxQueryThreshold(ref, att, &value, sizeof(val)) ); } + { IVX_CHECK_STATUS( vxQueryThreshold(ref, att, &val, sizeof(val)) ); } /// vxQueryThreshold(VX_THRESHOLD_TYPE) wrapper vx_enum type() const From 1c9262dce4af416c21bdfc869357bc575d718839 Mon Sep 17 00:00:00 2001 From: apavlenko Date: Mon, 21 Nov 2016 12:31:48 +0300 Subject: [PATCH 09/10] hiding silly warnings --- 3rdparty/openvx/include/ivx.hpp | 36 +++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/3rdparty/openvx/include/ivx.hpp b/3rdparty/openvx/include/ivx.hpp index cd36e071c7..2d3275dada 100644 --- a/3rdparty/openvx/include/ivx.hpp +++ b/3rdparty/openvx/include/ivx.hpp @@ -81,6 +81,21 @@ Details: TBD #include "opencv2/core.hpp" #endif +// disabling false alarm warnings +#if defined(_MSC_VER) + #pragma warning(push) + //#pragma warning( disable : 4??? ) +#elif defined(__clang__) + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wunused-local-typedef" + #pragma clang diagnostic ignored "-Wmissing-prototypes" +#elif defined(__GNUC__) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wunused-local-typedefs" + #pragma GCC diagnostic ignored "-Wunused-value" + #pragma GCC diagnostic ignored "-Wmissing-declarations" +#endif // compiler macro + namespace ivx { @@ -273,12 +288,12 @@ template <> struct RefTypeTraits /// Casting to vx_reference with compile-time check // takes 'vx_reference' itself and RefWrapper via 'operator vx_reference()' -vx_reference castToReference(vx_reference ref) +inline vx_reference castToReference(vx_reference ref) { return ref; } // takes vx_reference extensions that have RefTypeTraits specializations template -vx_reference castToReference(const T& ref, typename RefTypeTraits::vxType dummy = 0) +inline vx_reference castToReference(const T& ref, typename RefTypeTraits::vxType dummy = 0) { (void)dummy; return (vx_reference)ref; } #else @@ -302,7 +317,7 @@ struct is_ref::vxTypeEnum, void())> : std::true_typ /// Casting to vx_reference with compile-time check template -vx_reference castToReference(const T& obj) +inline vx_reference castToReference(const T& obj) { static_assert(is_ref::value, "unsupported conversion"); return (vx_reference) obj; @@ -1162,12 +1177,12 @@ static const vx_enum /// vxCopyImagePatch() wrapper (or vxAccessImagePatch() + vxCommitImagePatch() for OpenVX 1.0) void copy( vx_uint32 planeIdx, vx_rectangle_t rect, const vx_imagepatch_addressing_t& addr, void* data, - vx_enum usage, vx_enum memType = VX_MEMORY_TYPE_HOST ) + vx_enum usage, vx_enum memoryType = VX_MEMORY_TYPE_HOST ) { #ifdef VX_VERSION_1_1 - IVX_CHECK_STATUS(vxCopyImagePatch(ref, &rect, planeIdx, &addr, (void*)data, usage, memType)); + IVX_CHECK_STATUS(vxCopyImagePatch(ref, &rect, planeIdx, &addr, (void*)data, usage, memoryType)); #else - (void)memType; + (void)memoryType; vx_imagepatch_addressing_t* a = const_cast(&addr); IVX_CHECK_STATUS(vxAccessImagePatch(ref, &rect, planeIdx, a, &data, usage)); IVX_CHECK_STATUS(vxCommitImagePatch(ref, &rect, planeIdx, a, data)); @@ -1653,4 +1668,13 @@ Node gaussian3x3(vx_graph graph, vx_image inImg, vx_image outImg) } // namespace ivx +// restore warnings +#if defined(_MSC_VER) + #pragma warning(pop) +#elif defined(__clang__) + #pragma clang diagnostic pop +#elif defined(__GNUC__) + #pragma GCC diagnostic pop +#endif // compiler macro + #endif //IVX_HPP From f89ea6d7fa458bd4c03f1a661d13e0c00411dfec Mon Sep 17 00:00:00 2001 From: Rostislav Vasilikhin Date: Tue, 22 Nov 2016 16:27:06 +0300 Subject: [PATCH 10/10] hide info warnings --- samples/openvx/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/samples/openvx/CMakeLists.txt b/samples/openvx/CMakeLists.txt index 3f891f2794..f2a5680f43 100644 --- a/samples/openvx/CMakeLists.txt +++ b/samples/openvx/CMakeLists.txt @@ -15,6 +15,7 @@ if(BUILD_EXAMPLES AND OCV_DEPENDENCIES_FOUND) ocv_include_modules_recurse(${OPENCV_OPENVX_SAMPLE_REQUIRED_DEPS}) add_definitions(-DIVX_USE_OPENCV) + add_definitions(-DIVX_HIDE_INFO_WARNINGS) file(GLOB srcs_wrapped wrappers.cpp *.hpp) file(GLOB srcs_orig no_wrappers.cpp *.hpp)