Understood, and I could also use the OpenVX version of the call I assume (vxAndNode). But what if I don’t know my input image dimensions until runtime? For example, I know I want to mask off 64 bits from the left of the image, but I don’t know the image height yet. Or, I don’t know exactly how many bits I want to mask off until the loop begins.
I could just use OpenCV calls and do it in CPU, but I was hoping to fit this into the graph somehow and make it part of the CUDA image processing pipeline.
LATE EDIT: I had bugs in my static_cast call, and I switched to the non-deprecated API, but still no luck. Code below. I notice this isn’t part of the graph…how does the pipeline handle non-Node object functions being called?
vx_int16 maskedOffPixelValue = 0;
void* basePtr = NULL;
vx_imagepatch_addressing_t addr;
vx_map_id mapID;
vx_uint32 plane = 0;
vx_rectangle_t maskRect;
maskRect.start_x = 0;
maskRect.start_y = 0;
maskRect.end_x = 128;
maskRect.end_y = 960;
vx_status status = vxMapImagePatch(image, &maskRect, plane,
&mapID, &addr, &basePtr,
VX_WRITE_ONLY, VX_MEMORY_TYPE_HOST, 0);
for( vx_uint32 y = 0; y < addr.dim_y; y += addr.step_y )
{
for( vx_uint32 x = 0; x < addr.dim_x; x += addr.step_x )
{
vx_int16* ptr2 = static_cast<vx_int16*>(vxFormatImagePatchAddress2d(basePtr, x, y, &addr));
*ptr2 = maskedOffPixelValue;
}
} //end: for( ... )
status = vxUnmapImagePatch(image, mapID);
Here’s the OpenVX example I followed, from their 1.1 Reference Card:
vx_status status = VX_SUCCESS;
void *base_ptr = NULL;
vx_uint32 width = 640, height = 480, plane = 0;
vx_image image = vxCreateImage(context, width, height, VX_DF_IMAGE_U8);
vx_rectangle_t rect;
vx_imagepatch_addressing_t addr;
rect.start_x = rect.start_y = 0;
rect.end_x = rect.end_y = PATCH_DIM;
status = vxAccessImagePatch(image, &rect, plane,&addr, &base_ptr, VX_READ_AND_WRITE);
if (status == VX_SUCCESS)
{
vx_uint32 x,y,i,j;
vx_uint8 pixel = 0;
/* addressing options */
/* use linear addressing function/macro */
for (i = 0; i < addr.dim_x*addr.dim_y; i++) {
vx_uint8 *ptr2 = vxFormatImagePatchAddress1d(base_ptr, i, &addr);
*ptr2 = pixel;
}
/* 2d addressing option */
for (y = 0; y < addr.dim_y; y+=addr.step_y) {
for (x = 0; x < addr.dim_x; x+=addr.step_x) {
vx_uint8 *ptr2 = vxFormatImagePatchAddress2d(base_ptr, x, y, &addr);
*ptr2 = pixel;
}
}
/* direct addressing by client. for subsampled planes, scale will change. */
for (y = 0; y < addr.dim_y; y+=addr.step_y) {
j = (addr.stride_y*y*addr.scale_y)/VX_SCALE_UNITY;
for (x = 0; x < addr.dim_x; x+=addr.step_x) {
vx_uint8 *tmp = (vx_uint8 *)base_ptr;
i = j + (addr.stride_x*x*addr.scale_x) / VX_SCALE_UNITY;
tmp[i] = pixel;
}
}
/* commits the data back to the image. If rect were 0 or empty, it would just decrement
* the reference (used when reading an image only).
*/
status = vxCommitImagePatch(image, &rect, plane, &addr, base_ptr);
}
vxReleaseImage(&image);