CoreFlow 1.0.0
A modern orchestration and execution runtime
Loading...
Searching...
No Matches
bubble_pop.cpp

Bubble Pop Sample.

Bubble Pop Sample

Version
0.1
Date
2025-09-03
#include <string>
#include <VX/vx.h>
#include "vx_ext_pop.h"
using namespace cv;
using namespace std;
#define ERROR_CHECK_STATUS( status ) { \
vx_status status_ = (status); \
if(status_ != VX_SUCCESS) { \
printf("ERROR: failed with status = (%d) at " __FILE__ "#%d\n", status_, __LINE__); \
exit(1); \
} \
}
#define ERROR_CHECK_OBJECT( obj ) { \
vx_status status_ = vxGetStatus((vx_reference)(obj)); \
if(status_ != VX_SUCCESS) { \
printf("ERROR: failed with status = (%d) at " __FILE__ "#%d\n", status_, __LINE__); \
exit(1); \
} \
}
static void VX_CALLBACK log_callback(vx_context context, vx_reference ref, vx_status status, const vx_char string[])
{
(void)context;
(void)ref;
(void)status;
size_t len = strlen(string);
if (len > 0) {
printf("%s", string);
if (string[len - 1] != '\n')
printf("\n");
fflush(stdout);
}
}
int main(int argc, char **argv)
{
if (argc < 2) {
printf("Usage:\n"
"./vxPop --donut\n"
"./vxPop --bubble \n");
return 0;
}
int width = 720, height = 480;
// create OpenVX Context
vxRegisterLogCallback(context, log_callback, vx_false_e);
// load vx_pop kernels
ERROR_CHECK_STATUS(vxLoadKernels(context, "vx_pop"));
// create OpenVX Graph
vx_graph graph = vxCreateGraph(context);
// create OpenVX Images
vx_image input_rgb_image = vxCreateImage(context, width, height, VX_DF_IMAGE_RGB);
vx_image output_pop_image = vxCreateImage(context, width, height, VX_DF_IMAGE_U8);
ERROR_CHECK_OBJECT(input_rgb_image);
ERROR_CHECK_OBJECT(output_pop_image);
// create intermediate images
vx_image yuv_image = vxCreateVirtualImage(graph, width, height, VX_DF_IMAGE_IYUV);
vx_image luma_image = vxCreateVirtualImage(graph, width, height, VX_DF_IMAGE_U8);
vx_image output_canny_image = vxCreateVirtualImage(graph, width, height, VX_DF_IMAGE_U8);
vx_image output_skinTone_image = vxCreateVirtualImage(graph, width, height, VX_DF_IMAGE_U8);
vx_image output_canny_skinTone_image = vxCreateVirtualImage(graph, width, height, VX_DF_IMAGE_U8);
ERROR_CHECK_OBJECT(yuv_image);
ERROR_CHECK_OBJECT(luma_image);
ERROR_CHECK_OBJECT(output_canny_image);
ERROR_CHECK_OBJECT(output_skinTone_image);
ERROR_CHECK_OBJECT(output_canny_skinTone_image);
// create threshold variable
vx_int32 lower = 80, upper = 100;
vx_int32 gradient_size = 3;
// create intermediate images which are not accessed by the user to be mem optimized
vx_image R_image = vxCreateVirtualImage(graph, width, height, VX_DF_IMAGE_U8);
vx_image G_image = vxCreateVirtualImage(graph, width, height, VX_DF_IMAGE_U8);
vx_image B_image = vxCreateVirtualImage(graph, width, height, VX_DF_IMAGE_U8);
vx_image RmG_image = vxCreateVirtualImage(graph, width, height, VX_DF_IMAGE_U8);
vx_image RmB_image = vxCreateVirtualImage(graph, width, height, VX_DF_IMAGE_U8);
vx_image R95_image = vxCreateVirtualImage(graph, width, height, VX_DF_IMAGE_U8);
vx_image G40_image = vxCreateVirtualImage(graph, width, height, VX_DF_IMAGE_U8);
vx_image B20_image = vxCreateVirtualImage(graph, width, height, VX_DF_IMAGE_U8);
vx_image RmG15_image = vxCreateVirtualImage(graph, width, height, VX_DF_IMAGE_U8);
vx_image RmB0_image = vxCreateVirtualImage(graph, width, height, VX_DF_IMAGE_U8);
vx_image and1_image = vxCreateVirtualImage(graph, width, height, VX_DF_IMAGE_U8);
vx_image and2_image = vxCreateVirtualImage(graph, width, height, VX_DF_IMAGE_U8);
vx_image and3_image = vxCreateVirtualImage(graph, width, height, VX_DF_IMAGE_U8);
ERROR_CHECK_OBJECT(RmG_image);
ERROR_CHECK_OBJECT(RmB_image);
ERROR_CHECK_OBJECT(R95_image);
ERROR_CHECK_OBJECT(G40_image);
ERROR_CHECK_OBJECT(B20_image);
ERROR_CHECK_OBJECT(RmG15_image);
ERROR_CHECK_OBJECT(RmB0_image);
ERROR_CHECK_OBJECT(and1_image);
ERROR_CHECK_OBJECT(and2_image);
ERROR_CHECK_OBJECT(and3_image);
// create threshold values
vx_int32 thresValue95 = 95;
ERROR_CHECK_OBJECT(thresh95);
vx_int32 thresValue40 = 40;
ERROR_CHECK_OBJECT(thresh40);
vx_int32 thresValue20 = 20;
ERROR_CHECK_OBJECT(thresh20);
vx_int32 thresValue15 = 15;
ERROR_CHECK_OBJECT(thresh15);
vx_int32 thresValue0 = 0;
// add nodes to the graph
string option = argv[1];
if (option == "--bubble")
{
vx_node nodes[] =
{
// extract R,G,B channels and compute R-G and R-B
vxChannelExtractNode(graph, input_rgb_image, VX_CHANNEL_R, R_image),
vxChannelExtractNode(graph, input_rgb_image, VX_CHANNEL_G, G_image),
vxChannelExtractNode(graph, input_rgb_image, VX_CHANNEL_B, B_image),
vxSubtractNode(graph, R_image, G_image, VX_CONVERT_POLICY_SATURATE, RmG_image),
vxSubtractNode(graph, R_image, B_image, VX_CONVERT_POLICY_SATURATE, RmB_image),
// compute threshold
vxThresholdNode(graph, R_image, thresh95, R95_image),
vxThresholdNode(graph, G_image, thresh40, G40_image),
vxThresholdNode(graph, B_image, thresh20, B20_image),
vxThresholdNode(graph, RmG_image, thresh15, RmG15_image),
vxThresholdNode(graph, RmB_image, thresh0, RmB0_image),
// aggregate all thresholded values to produce SKIN pixels
vxAndNode(graph, R95_image, G40_image, and1_image),
vxAndNode(graph, and1_image, B20_image, and2_image),
vxAndNode(graph, RmG15_image, RmB0_image, and3_image),
vxAndNode(graph, and2_image, and3_image, output_skinTone_image),
// create canny edge
vxColorConvertNode(graph, input_rgb_image, yuv_image),
vxChannelExtractNode(graph, yuv_image, VX_CHANNEL_Y, luma_image),
vxCannyEdgeDetectorNode(graph, luma_image, hyst, gradient_size, VX_NORM_L1, output_canny_image),
// or - canny & skintone images
vxOrNode(graph, output_canny_image, output_skinTone_image, output_canny_skinTone_image),
// vx pop - bubble pop
vxExtPopNode_bubblePop(graph, output_canny_skinTone_image, output_pop_image)
};
for( vx_size i = 0; i < sizeof( nodes ) / sizeof( nodes[0] ); i++ )
{
ERROR_CHECK_OBJECT( nodes[i] );
}
}
else
{
vx_node nodes[] =
{
// extract R,G,B channels and compute R-G and R-B
vxChannelExtractNode(graph, input_rgb_image, VX_CHANNEL_R, R_image),
vxChannelExtractNode(graph, input_rgb_image, VX_CHANNEL_G, G_image),
vxChannelExtractNode(graph, input_rgb_image, VX_CHANNEL_B, B_image),
vxSubtractNode(graph, R_image, G_image, VX_CONVERT_POLICY_SATURATE, RmG_image),
vxSubtractNode(graph, R_image, B_image, VX_CONVERT_POLICY_SATURATE, RmB_image),
// compute threshold
vxThresholdNode(graph, R_image, thresh95, R95_image),
vxThresholdNode(graph, G_image, thresh40, G40_image),
vxThresholdNode(graph, B_image, thresh20, B20_image),
vxThresholdNode(graph, RmG_image, thresh15, RmG15_image),
vxThresholdNode(graph, RmB_image, thresh0, RmB0_image),
// aggregate all thresholded values to produce SKIN pixels
vxAndNode(graph, R95_image, G40_image, and1_image),
vxAndNode(graph, and1_image, B20_image, and2_image),
vxAndNode(graph, RmG15_image, RmB0_image, and3_image),
vxAndNode(graph, and2_image, and3_image, output_skinTone_image),
// create canny edge
vxColorConvertNode(graph, input_rgb_image, yuv_image),
vxChannelExtractNode(graph, yuv_image, VX_CHANNEL_Y, luma_image),
vxCannyEdgeDetectorNode(graph, luma_image, hyst, gradient_size, VX_NORM_L1, output_canny_image),
// or - canny & skintone images
vxOrNode(graph, output_canny_image, output_skinTone_image, output_canny_skinTone_image),
// vx pop - donut pop
vxExtPopNode_donutPop(graph, output_canny_skinTone_image, output_pop_image)
};
for( vx_size i = 0; i < sizeof( nodes ) / sizeof( nodes[0] ); i++ )
{
ERROR_CHECK_OBJECT( nodes[i] );
}
}
// verify graph - only once
Mat input, input_rgb;
cv::namedWindow("VX POP - LIVE", cv::WINDOW_GUI_EXPANDED);
VideoCapture cap(0);
if (!cap.isOpened()) {
printf("Unable to open camera\n");
return 0;
}
for(;;)
{
cap >> input;
resize(input, input, Size(width, height));
cvtColor(input, input_rgb, COLOR_BGR2RGB);
if(waitKey(30) >= 0) break;
vx_rectangle_t cv_rgb_image_region;
cv_rgb_image_region.start_x = 0;
cv_rgb_image_region.start_y = 0;
cv_rgb_image_region.end_x = width;
cv_rgb_image_region.end_y = height;
vx_imagepatch_addressing_t cv_rgb_image_layout{};
cv_rgb_image_layout.dim_x = input_rgb.cols;
cv_rgb_image_layout.dim_y = input_rgb.rows;
cv_rgb_image_layout.stride_x = input_rgb.elemSize();
cv_rgb_image_layout.stride_y = input_rgb.step;
vx_uint8 * cv_rgb_image_buffer = input_rgb.data;
ERROR_CHECK_STATUS( vxCopyImagePatch( input_rgb_image, &cv_rgb_image_region, 0,
&cv_rgb_image_layout, cv_rgb_image_buffer,
vx_rectangle_t rect = { 0, 0, (vx_uint32)width, (vx_uint32)height };
vx_map_id map_id;
void * ptr;
ERROR_CHECK_STATUS( vxMapImagePatch( output_pop_image, &rect, 0, &map_id, &addr, &ptr,
Mat mat( height, width, CV_8U, ptr, addr.stride_y );
imshow( "VX POP - LIVE", mat );
if(waitKey(30) >= 0) break;
ERROR_CHECK_STATUS( vxUnmapImagePatch( output_pop_image, map_id ) );
}
// release objects
ERROR_CHECK_STATUS(vxReleaseImage( &output_canny_image ) );
ERROR_CHECK_STATUS(vxReleaseImage( &input_rgb_image ) );
ERROR_CHECK_STATUS(vxReleaseImage( &output_skinTone_image ));
ERROR_CHECK_STATUS(vxReleaseImage( &output_canny_skinTone_image ));
ERROR_CHECK_STATUS(vxReleaseImage( &output_pop_image ) );
return 0;
}
int main()
Definition blur_pipeline.cpp:15
#define ERROR_CHECK_OBJECT(obj)
Definition bubble_pop.cpp:28
#define ERROR_CHECK_STATUS(status)
Definition bubble_pop.cpp:20
uint32_t vx_uint32
A 32-bit unsigned value.
Definition vx_types.h:85
size_t vx_size
A wrapper of size_t to keep the naming convention uniform.
Definition vx_types.h:186
vx_enum vx_status
A formal status type with known fixed size.
Definition vx_types.h:550
int32_t vx_int32
A 32-bit signed value.
Definition vx_types.h:105
struct _vx_rectangle_t vx_rectangle_t
The rectangle data structure that is shared with the users. The area of the rectangle can be computed...
char vx_char
An 8 bit ASCII character.
Definition vx_types.h:70
uint8_t vx_uint8
An 8-bit unsigned value.
Definition vx_types.h:75
#define VX_CALLBACK
Defines calling convention for user callbacks.
Definition vx_types.h:63
@ VX_DF_IMAGE_IYUV
A 3 plane of 8-bit 4:2:0 sampled Y, U, V planes. This uses the BT709 full range by default.
Definition vx_types.h:841
@ VX_DF_IMAGE_RGB
A single plane of 24-bit pixel as 3 interleaved 8-bit units of R then G then B data....
Definition vx_types.h:816
@ VX_DF_IMAGE_U8
A single plane of unsigned 8-bit data. The range of data is not specified, as it may be extracted fro...
Definition vx_types.h:855
@ vx_false_e
The "false" value.
Definition vx_types.h:404
@ VX_TYPE_UINT8
A vx_uint8.
Definition vx_types.h:437
@ VX_CONVERT_POLICY_SATURATE
Results are saturated to the bit depth of the output operand.
Definition vx_types.h:803
@ VX_CHANNEL_B
Use to extract the BLUE channel, no matter the byte or packing order.
Definition vx_types.h:1319
@ VX_CHANNEL_G
Use to extract the GREEN channel, no matter the byte or packing order.
Definition vx_types.h:1317
@ VX_CHANNEL_Y
Use to extract the LUMA channel, no matter the byte or packing order.
Definition vx_types.h:1323
@ VX_CHANNEL_R
Use to extract the RED channel, no matter the byte or packing order.
Definition vx_types.h:1315
struct Context * vx_context
An opaque reference to the implementation context.
Definition vx_types.h:274
VX_API_ENTRY vx_context VX_API_CALL vxCreateContext(void)
Creates a vx_context.
VX_API_ENTRY vx_status VX_API_CALL vxReleaseContext(vx_context *context)
Releases the OpenVX object context.
@ VX_READ_ONLY
The memory shall be treated by the system as if it were read-only. If the User writes to this memory,...
Definition vx_types.h:1515
@ VX_WRITE_ONLY
The memory shall be treated by the system as if it were write-only. If the User reads from this memor...
Definition vx_types.h:1519
@ VX_MEMORY_TYPE_HOST
The default memory type to import from the Host.
Definition vx_types.h:1338
VX_API_ENTRY vx_status VX_API_CALL vxVerifyGraph(vx_graph graph)
Verifies the state of the graph before it is executed. This is useful to catch programmer errors and ...
VX_API_ENTRY vx_status VX_API_CALL vxReleaseGraph(vx_graph *graph)
Releases a reference to a graph. The object may not be garbage collected until its total reference co...
VX_API_ENTRY vx_graph VX_API_CALL vxCreateGraph(vx_context context)
Creates an empty graph.
struct Graph * vx_graph
An opaque reference to a graph.
Definition vx_types.h:263
VX_API_ENTRY vx_status VX_API_CALL vxProcessGraph(vx_graph graph)
This function causes the synchronous processing of a graph. If the graph has not been verified,...
VX_API_ENTRY vx_image VX_API_CALL vxCreateVirtualImage(vx_graph graph, vx_uint32 width, vx_uint32 height, vx_df_image color)
Creates an opaque reference to an image buffer with no direct user access. This function allows setti...
struct _vx_imagepatch_addressing_t vx_imagepatch_addressing_t
The addressing image patch structure is used by the Host only to address pixels in an image patch....
VX_API_ENTRY vx_status VX_API_CALL vxUnmapImagePatch(vx_image image, vx_map_id map_id)
Unmap and commit potential changes to a image object patch that were previously mapped....
VX_API_ENTRY vx_status VX_API_CALL vxMapImagePatch(vx_image image, const vx_rectangle_t *rect, vx_uint32 plane_index, vx_map_id *map_id, vx_imagepatch_addressing_t *addr, void **ptr, vx_enum usage, vx_enum mem_type, vx_uint32 flags)
Allows the application to get direct access to a rectangular patch of an image object plane.
struct Image * vx_image
An opaque reference to an image.
Definition vx_types.h:219
VX_API_ENTRY vx_status VX_API_CALL vxReleaseImage(vx_image *image)
Releases a reference to an image object. The object may not be garbage collected until its total refe...
uintptr_t vx_map_id
Holds the address of a variable where the map/unmap functions return a map identifier.
Definition vx_types.h:196
VX_API_ENTRY vx_status VX_API_CALL vxCopyImagePatch(vx_image image, const vx_rectangle_t *image_rect, vx_uint32 image_plane_index, const vx_imagepatch_addressing_t *user_addr, void *user_ptr, vx_enum usage, vx_enum user_mem_type)
Allows the application to copy a rectangular patch from/into an image object plane.
VX_API_ENTRY vx_image VX_API_CALL vxCreateImage(vx_context context, vx_uint32 width, vx_uint32 height, vx_df_image color)
Creates an opaque reference to an image buffer.
@ VX_NOGAP_X
No Gap.
Definition vx_types.h:1969
VX_API_ENTRY void VX_API_CALL vxRegisterLogCallback(vx_context context, vx_log_callback_f callback, vx_bool reentrant)
Registers a callback facility to the OpenVX implementation to receive error logs.
struct Node * vx_node
An opaque reference to a kernel node.
Definition vx_types.h:253
VX_API_ENTRY vx_status VX_API_CALL vxReleaseNode(vx_node *node)
Releases a reference to a Node object. The object may not be garbage collected until its total refere...
VX_API_ENTRY vx_status VX_API_CALL vxSetThresholdAttribute(vx_threshold thresh, vx_enum attribute, const void *ptr, vx_size size)
Sets attributes on the threshold object.
struct Threshold * vx_threshold
The Threshold Object. A thresholding object contains the types and limit values of the thresholding r...
Definition vx_types.h:338
VX_API_ENTRY vx_status VX_API_CALL vxReleaseThreshold(vx_threshold *thresh)
Releases a reference to a threshold object. The object may not be garbage collected until its total r...
@ VX_THRESHOLD_TYPE_RANGE
A threshold with 2 values (upper/lower). Use with Canny Edge Detection.
Definition vx_types.h:1167
@ VX_THRESHOLD_TYPE_BINARY
A threshold with only 1 value.
Definition vx_types.h:1165
VX_API_ENTRY vx_status VX_API_CALL vxLoadKernels(vx_context context, const vx_char *module)
Loads a library of kernels, called module, into a context.
VX_API_ENTRY vx_node VX_API_CALL vxAndNode(vx_graph graph, vx_image in1, vx_image in2, vx_image out)
[Graph] Creates a bitwise AND node.
VX_API_ENTRY vx_node VX_API_CALL vxCannyEdgeDetectorNode(vx_graph graph, vx_image input, vx_threshold hyst, vx_int32 gradient_size, vx_enum norm_type, vx_image output)
[Graph] Creates a Canny Edge Detection Node.
@ VX_NORM_L1
The L1 normalization.
Definition vx_types.h:1490
VX_API_ENTRY vx_node VX_API_CALL vxChannelExtractNode(vx_graph graph, vx_image input, vx_enum channel, vx_image output)
[Graph] Creates a channel extract node.
VX_API_ENTRY vx_node VX_API_CALL vxColorConvertNode(vx_graph graph, vx_image input, vx_image output)
[Graph] Creates a color conversion node.
VX_API_ENTRY vx_node VX_API_CALL vxOrNode(vx_graph graph, vx_image in1, vx_image in2, vx_image out)
[Graph] Creates a bitwise INCLUSIVE OR node.
VX_API_ENTRY vx_node VX_API_CALL vxSubtractNode(vx_graph graph, vx_image in1, vx_image in2, vx_enum policy, vx_image out)
[Graph] Creates an arithmetic subtraction node.
VX_API_ENTRY vx_node VX_API_CALL vxThresholdNode(vx_graph graph, vx_image input, vx_threshold thresh, vx_image output)
[Graph] Creates a Threshold node and returns a reference to it.
vx_int32 stride_y
Stride in Y dimension in bytes.
Definition vx_types.h:1644
vx_uint32 start_x
The Start X coordinate.
Definition vx_types.h:1771
vx_uint32 start_y
The Start Y coordinate.
Definition vx_types.h:1772
vx_uint32 end_y
The End Y coordinate.
Definition vx_types.h:1774
vx_uint32 end_x
The End X coordinate.
Definition vx_types.h:1773
The top level OpenVX Header.
#define VX_THRESHOLD_ATTRIBUTE_THRESHOLD_LOWER
Definition vx_compatibility.h:98
#define VX_THRESHOLD_ATTRIBUTE_THRESHOLD_UPPER
Definition vx_compatibility.h:99
#define VX_THRESHOLD_THRESHOLD_VALUE
Definition vx_compatibility.h:156
VX_API_ENTRY vx_threshold VX_API_CALL vxCreateThreshold(vx_context c, vx_enum thresh_type, vx_enum data_type)
SHARED_PUBLIC vx_node VX_API_CALL vxExtPopNode_donutPop(vx_graph graph, vx_image input, vx_image output)
[Graph] Creates a OpenCV blur function node.
Definition internal_vxNodes.cpp:93
SHARED_PUBLIC vx_node VX_API_CALL vxExtPopNode_bubblePop(vx_graph graph, vx_image input, vx_image output)
[Graph] Creates a OpenCV blur function node.
Definition internal_vxNodes.cpp:76
struct Reference * vx_reference
Definition vx_types.h:173