Пример #1
0
// nodeless version of the Not kernel
vx_status vxNot(vx_image input, vx_image output)
{
    vx_uint32 y, x, width = 0, height = 0;
    void *dst_base = NULL;
    void *src_base = NULL;
    vx_imagepatch_addressing_t dst_addr, src_addr;
    vx_rectangle_t rect;
    vx_status status = VX_SUCCESS;

    status = vxGetValidRegionImage(input, &rect);
    status |= vxAccessImagePatch(input, &rect, 0, &src_addr, (void **)&src_base, VX_READ_ONLY);
    status |= vxAccessImagePatch(output, &rect, 0, &dst_addr, (void **)&dst_base, VX_WRITE_ONLY);
    height = src_addr.dim_y;
    width = src_addr.dim_x;
    for (y = 0; y < height; y++)
    {
        for (x = 0; x < width; x++)
        {
            vx_uint8 *src = vxFormatImagePatchAddress2d(src_base, x, y, &src_addr);
            vx_uint8 *dst = vxFormatImagePatchAddress2d(dst_base, x, y, &dst_addr);

            *dst = ~*src;
        }
    }
    status |= vxCommitImagePatch(input, NULL, 0, &src_addr, src_base);
    status |= vxCommitImagePatch(output, &rect, 0, &dst_addr, dst_base);

    return status;
}
Пример #2
0
// generic bitwise op
static vx_status vxBinaryU8Op(vx_image in1, vx_image in2, vx_image output, bitwiseOp op)
{
    vx_uint32 y, x, width = 0, height = 0;
    void *dst_base   = NULL;
    void *src_base[2] = {NULL, NULL};
    vx_imagepatch_addressing_t dst_addr, src_addr[2];
    vx_rectangle_t rect;
    vx_status status = VX_SUCCESS;

    status = vxGetValidRegionImage(in1, &rect);
    status |= vxAccessImagePatch(in1, &rect, 0, &src_addr[0], (void **)&src_base[0], VX_READ_ONLY);
    status |= vxAccessImagePatch(in2, &rect, 0, &src_addr[1], (void **)&src_base[1], VX_READ_ONLY);
    status |= vxAccessImagePatch(output, &rect, 0, &dst_addr, (void **)&dst_base, VX_WRITE_ONLY);
    width = src_addr[0].dim_x;
    height = src_addr[0].dim_y;
    for (y = 0; y < height; y++)
    {
        for (x = 0; x < width; x++)
        {
            vx_uint8 *src[2] = {
                vxFormatImagePatchAddress2d(src_base[0], x, y, &src_addr[0]),
                vxFormatImagePatchAddress2d(src_base[1], x, y, &src_addr[1]),
            };
            vx_uint8 *dst = vxFormatImagePatchAddress2d(dst_base, x, y, &dst_addr);

            *dst = op(*src[0], *src[1]);
        }
    }
    status |= vxCommitImagePatch(in1, NULL, 0, &src_addr[0], src_base[0]);
    status |= vxCommitImagePatch(in2, NULL, 0, &src_addr[1], src_base[1]);
    status |= vxCommitImagePatch(output, &rect, 0, &dst_addr, dst_base);

    return status;
}
Пример #3
0
static vx_status vxMagnitudeKernel(vx_node node, vx_reference *parameters, vx_uint32 num)
{
    vx_status status = VX_FAILURE;
    if (num == 3)
    {
        vx_image grad_x = (vx_image)parameters[0];
        vx_image grad_y = (vx_image)parameters[1];
        vx_image output = (vx_image)parameters[2];
        vx_uint32 y, x;
        vx_fourcc format = 0;
        vx_uint8 *dst_base   = NULL;
        vx_int16 *src_base_x = NULL;
        vx_int16 *src_base_y = NULL;
        vx_imagepatch_addressing_t dst_addr, src_addr_x, src_addr_y;
        vx_rectangle rect;
        vx_uint32 value;

        if (grad_x == 0 || grad_y == 0)
            return VX_ERROR_INVALID_PARAMETERS;
        vxQueryImage(output, VX_IMAGE_ATTRIBUTE_FORMAT, &format, sizeof(format));
        rect = vxGetValidRegionImage(grad_x);
        status = VX_SUCCESS;
        status |= vxAccessImagePatch(grad_x, rect, 0, &src_addr_x, (void **)&src_base_x);
        status |= vxAccessImagePatch(grad_y, rect, 0, &src_addr_y, (void **)&src_base_y);
        status |= vxAccessImagePatch(output, rect, 0, &dst_addr, (void **)&dst_base);
        for (y = 0; y < src_addr_x.dim_y; y++)
        {
            for (x = 0; x < src_addr_x.dim_x; x++)
            {
                vx_int16 *in_x = vxFormatImagePatchAddress2d(src_base_x, x, y, &src_addr_x);
                vx_int16 *in_y = vxFormatImagePatchAddress2d(src_base_y, x, y, &src_addr_y);
                if (format == FOURCC_U8)
                {
                    vx_uint8 *dst = vxFormatImagePatchAddress2d(dst_base, x, y, &dst_addr);
                    vx_int32 grad[2] = {in_x[0]*in_x[0], in_y[0]*in_y[0]};
                    vx_float64 sum = grad[0] + grad[1];
                    value = ((vx_int32)sqrt(sum))/4;
                    *dst = (vx_uint8)(value > UINT8_MAX ? UINT8_MAX : value);
                }
                else if (format == FOURCC_S16)
                {
                    vx_int16 *dst = vxFormatImagePatchAddress2d(dst_base, x, y, &dst_addr);
                    vx_int32 grad[2] = {in_x[0]*in_x[0], in_y[0]*in_y[0]};
                    vx_float64 sum = grad[0] + grad[1];
                    value = (vx_int32)sqrt(sum);
                    *dst = (vx_int16)(value > INT16_MAX ? INT16_MAX : value);
                }
            }
        }
        status |= vxCommitImagePatch(grad_x, 0, 0, &src_addr_x, src_base_x);
        status |= vxCommitImagePatch(grad_y, 0, 0, &src_addr_y, src_base_y);
        status |= vxCommitImagePatch(output, rect, 0, &dst_addr, dst_base);
        vxReleaseRectangle(&rect);
    }
    return status;
}
Пример #4
0
static vx_status vxPhaseKernel(vx_node node, vx_reference *parameters, vx_uint32 num)
{
    vx_status status = VX_FAILURE;
    if (num == 3)
    {
        vx_image grad_x = (vx_image)parameters[0];
        vx_image grad_y = (vx_image)parameters[1];
        vx_image output = (vx_image)parameters[2];
        vx_uint32 y, x;
        vx_uint8 *dst_base   = NULL;
        vx_int16 *src_base_x = NULL;
        vx_int16 *src_base_y = NULL;
        vx_imagepatch_addressing_t dst_addr, src_addr_x, src_addr_y;
        vx_rectangle rect;
        if (grad_x == 0 && grad_y == 0)
            return VX_ERROR_INVALID_PARAMETERS;

        rect = vxGetValidRegionImage(grad_x);
        status = VX_SUCCESS;
        status |= vxAccessImagePatch(grad_x, rect, 0, &src_addr_x, (void **)&src_base_x);
        status |= vxAccessImagePatch(grad_y, rect, 0, &src_addr_y, (void **)&src_base_y);
        status |= vxAccessImagePatch(output, rect, 0, &dst_addr, (void **)&dst_base);
        for (y = 0; y < dst_addr.dim_y; y++)
        {
            for (x = 0; x < dst_addr.dim_x; x++)
            {
                vx_int16 *in_x = vxFormatImagePatchAddress2d(src_base_x, x, y, &src_addr_x);
                vx_int16 *in_y = vxFormatImagePatchAddress2d(src_base_y, x, y, &src_addr_y);
                vx_uint8 *dst = vxFormatImagePatchAddress2d(dst_base, x, y, &dst_addr);
                /* -M_PI to M_PI */
                double arct = atan2((double)in_y[0],(double)in_x[0]);
                /* 0.0 - 1.0 */
                double norm = arct;
                if (arct < 0.0)
                {
                    norm = VX_TAU + arct;
                }
                /* 0 - 255 */
                *dst = (vx_uint8)((vx_uint32)(norm * 255u) & 0xFFu);
                if (in_y[0] != 0 || in_x[0] != 0)
                {
                    VX_PRINT(VX_ZONE_INFO, "atan2(%d,%d) = %lf [norm=%lf] dst=%02x\n", in_y[0], in_x[0], arct, norm, *dst);
                }
            }
        }
        status |= vxCommitImagePatch(grad_x, 0, 0, &src_addr_x, src_base_x);
        status |= vxCommitImagePatch(grad_y, 0, 0, &src_addr_y, src_base_y);
        status |= vxCommitImagePatch(output, rect, 0, &dst_addr, dst_base);
        vxReleaseRectangle(&rect);
    }
    return status;
}
Пример #5
0
vx_status vxConvolution3x3(vx_image src, vx_image dst, vx_int16 conv[3][3], const vx_border_mode_t *borders)
{
    vx_uint32 y, x;
    void *src_base = NULL;
    void *dst_base = NULL;
    vx_imagepatch_addressing_t src_addr, dst_addr;
    vx_rectangle_t rect;
    vx_enum dst_format = VX_DF_IMAGE_VIRT;
    vx_status status = VX_SUCCESS;
    vx_uint32 low_x = 0, low_y = 0, high_x, high_y;

    status = vxGetValidRegionImage(src, &rect);
    status |= vxAccessImagePatch(src, &rect, 0, &src_addr, &src_base, VX_READ_ONLY);
    status |= vxAccessImagePatch(dst, &rect, 0, &dst_addr, &dst_base, VX_WRITE_ONLY);
    status |= vxQueryImage(dst, VX_IMAGE_ATTRIBUTE_FORMAT, &dst_format, sizeof(dst_format));

    high_x = src_addr.dim_x;
    high_y = src_addr.dim_y;

    if (borders->mode == VX_BORDER_MODE_UNDEFINED)
    {
        ++low_x; --high_x;
        ++low_y; --high_y;
        vxAlterRectangle(&rect, 1, 1, -1, -1);
    }
    //printf("%s Rectangle = {%u,%u x %u,%u}\n",__FUNCTION__, rect.start_x, rect.start_y, rect.end_x, rect.end_y);

    for (y = low_y; y < high_y; y++)
    {
        for (x = low_x; x < high_x; x++)
        {
            vx_int32 value = vx_convolve8with16(src_base, x, y, &src_addr, conv, borders);

            if (dst_format == VX_DF_IMAGE_U8)
            {
                vx_uint8 *dst = vxFormatImagePatchAddress2d(dst_base, x, y, &dst_addr);
                *dst = vx_clamp_u8_i32(value);
            }
            else
            {
                vx_int16 *dst = vxFormatImagePatchAddress2d(dst_base, x, y, &dst_addr);
                *dst = vx_clamp_s16_i32(value);
            }
        }
    }

    status |= vxCommitImagePatch(src, NULL, 0, &src_addr, src_base);
    status |= vxCommitImagePatch(dst, &rect, 0, &dst_addr, dst_base);
    return status;
}
Пример #6
0
// read image
int ReadImage(vx_image image, vx_rectangle_t * rectFull, FILE * fp)
{
	// get number of planes, image format, and pixel type
	vx_df_image format = VX_DF_IMAGE_VIRT;
	vx_size num_planes = 0;
	ERROR_CHECK(vxQueryImage(image, VX_IMAGE_ATTRIBUTE_FORMAT, &format, sizeof(format)));
	ERROR_CHECK(vxQueryImage(image, VX_IMAGE_ATTRIBUTE_PLANES, &num_planes, sizeof(num_planes)));
	// read all image planes into vx_image and check if EOF has occured while reading
	bool eofDetected = false;
	for (vx_uint32 plane = 0; plane < (vx_uint32)num_planes; plane++){
		vx_imagepatch_addressing_t addr;
		vx_uint8 * src = NULL;
		ERROR_CHECK(vxAccessImagePatch(image, rectFull, plane, &addr, (void **)&src, VX_WRITE_ONLY));
		vx_size width = (addr.dim_x * addr.scale_x) / VX_SCALE_UNITY;
		vx_size width_in_bytes = (format == VX_DF_IMAGE_U1_AMD) ? ((width + 7) >> 3) : (width * addr.stride_x);
		for (vx_uint32 y = 0; y < addr.dim_y; y += addr.step_y){
			vx_uint8 *srcp = (vx_uint8 *)vxFormatImagePatchAddress2d(src, 0, y, &addr);
			if (fread(srcp, 1, width_in_bytes, fp) != width_in_bytes) {
				eofDetected = true;
				break;
			}
		}
		ERROR_CHECK(vxCommitImagePatch(image, rectFull, plane, &addr, src));
	}
	// return 1 if EOF detected, other 0
	return eofDetected ? 1 : 0;
}
Пример #7
0
static vx_status map_vx_image(vx_image vxImg, uint32_t *width, uint32_t *height, mem_info_t *mem_info, vx_enum usage)
{
	vx_size vxImgSize;
	vx_status status = VX_SUCCESS;
	vx_rectangle_t rect;
	vx_imagepatch_addressing_t vxImg_addr;
	void *vxImg_base = NULL;
	
	status = vxGetValidRegionImage(vxImg, &rect);
	if(status != VX_SUCCESS) return status;
	
	status = vxAccessImagePatch(vxImg, &rect, 0, &vxImg_addr, (void **)&vxImg_base, usage);
	if(status != VX_SUCCESS) return status;
	
    *width  = vxImg_addr.dim_x;
    *height = vxImg_addr.dim_y;
	
	status = get_vx_image_size(vxImg, &vxImgSize);
	if(status != VX_SUCCESS) return status;
	
	mem_info->len = vxImgSize;
	mem_info->ptr = vxImg_base;
	mem_info->vxImg_addr = vxImg_addr;
	
	return status;
}
Пример #8
0
static vx_status VX_CALLBACK vxCopyImagePtrKernel(vx_node node, const vx_reference *parameters, vx_uint32 num)
{
    vx_status status = VX_FAILURE;
    if (num == 2)
    {
        vx_scalar input = (vx_scalar)parameters[0];
        vx_image output = (vx_image)parameters[1];
        vx_uint32 width = 0, height = 0, p = 0, y = 0, len = 0;
        vx_size planes = 0;
        void *src = NULL;
        void *dst = NULL;
        vx_imagepatch_addressing_t dst_addr;
        vx_rectangle_t rect;
        vx_uint8 *srcp = NULL;

        vxReadScalarValue(input, &src);
        srcp = (vx_uint8 *)src;

        status = VX_SUCCESS; // assume success until an error occurs.
        status |= vxQueryImage(output, VX_IMAGE_ATTRIBUTE_WIDTH, &width, sizeof(width));
        status |= vxQueryImage(output, VX_IMAGE_ATTRIBUTE_HEIGHT, &height, sizeof(height));
        status |= vxQueryImage(output, VX_IMAGE_ATTRIBUTE_PLANES, &planes, sizeof(planes));
        rect.start_x = rect.start_y = 0;
        rect.end_x = width;
        rect.end_y = height;
        for (p = 0; p < planes && status == VX_SUCCESS; p++)
        {
            status = VX_SUCCESS;
            status |= vxAccessImagePatch(output, &rect, p, &dst_addr, &dst, VX_WRITE_ONLY);
            for (y = 0; y < height && status == VX_SUCCESS; y+=dst_addr.step_y)
            {
                vx_uint8 *dstp = vxFormatImagePatchAddress2d(dst, 0, y, &dst_addr);
                len = (dst_addr.stride_x * dst_addr.dim_x * dst_addr.scale_x) / VX_SCALE_UNITY;
                memcpy(dstp, srcp, len);
                srcp += len;
            }
            if (status == VX_SUCCESS) {
                status |= vxCommitImagePatch(output, &rect, p, &dst_addr, dst);
            }
        }
    }
    else
    {
        status = VX_ERROR_INVALID_PARAMETERS;
    }
    return status;
}
Пример #9
0
// write image
int WriteImage(vx_image image, vx_rectangle_t * rectFull, FILE * fp)
{
	// get number of planes, image format, and pixel type
	vx_df_image format = VX_DF_IMAGE_VIRT;
	vx_size num_planes = 0;
	ERROR_CHECK(vxQueryImage(image, VX_IMAGE_ATTRIBUTE_FORMAT, &format, sizeof(format)));
	ERROR_CHECK(vxQueryImage(image, VX_IMAGE_ATTRIBUTE_PLANES, &num_planes, sizeof(num_planes)));
	// write all image planes from vx_image
	bool eofDetected = false;
	for (vx_uint32 plane = 0; plane < (vx_uint32)num_planes; plane++){
		vx_imagepatch_addressing_t addr;
		vx_uint8 * src = NULL;
		ERROR_CHECK(vxAccessImagePatch(image, rectFull, plane, &addr, (void **)&src, VX_READ_ONLY));
		vx_size width = (addr.dim_x * addr.scale_x) / VX_SCALE_UNITY;
		vx_size width_in_bytes = (format == VX_DF_IMAGE_U1_AMD) ? ((width + 7) >> 3) : (width * addr.stride_x);
		for (vx_uint32 y = 0; y < addr.dim_y; y += addr.step_y){
			vx_uint8 *srcp = (vx_uint8 *)vxFormatImagePatchAddress2d(src, 0, y, &addr);
			fwrite(srcp, 1, width_in_bytes, fp);
		}
		ERROR_CHECK(vxCommitImagePatch(image, rectFull, plane, &addr, src));
	}
	return 0;
}
Пример #10
0
// Compute checksum of rectangular region specified within an image
void ComputeChecksum(char checkSumString[64], vx_image image, vx_rectangle_t * rectRegion)
{
	// get number of planes
	vx_df_image format = VX_DF_IMAGE_VIRT;
	vx_size num_planes = 0;
	ERROR_CHECK(vxQueryImage(image, VX_IMAGE_ATTRIBUTE_FORMAT, &format, sizeof(format)));
	ERROR_CHECK(vxQueryImage(image, VX_IMAGE_ATTRIBUTE_PLANES, &num_planes, sizeof(num_planes)));
	// compute checksum
	CHasher checksum; checksum.Initialize();
	for (vx_uint32 plane = 0; plane < (vx_uint32)num_planes; plane++) {
		vx_imagepatch_addressing_t addr;
		vx_uint8 * base_ptr = nullptr;
		ERROR_CHECK(vxAccessImagePatch(image, rectRegion, plane, &addr, (void **)&base_ptr, VX_READ_ONLY));
		vx_uint32 width = ((addr.dim_x * addr.scale_x) / VX_SCALE_UNITY);
		vx_uint32 height = ((addr.dim_y * addr.scale_y) / VX_SCALE_UNITY);
		vx_uint32 width_in_bytes = (format == VX_DF_IMAGE_U1_AMD) ? ((width + 7) >> 3) : (width * addr.stride_x);
		for (vx_uint32 y = 0; y < height; y++) {
			checksum.Process(base_ptr + y * addr.stride_y, width_in_bytes);
		}
		ERROR_CHECK(vxCommitImagePatch(image, rectRegion, plane, &addr, base_ptr));
	}
	// copy the checksum string
	strcpy(checkSumString, checksum.GetCheckSum());
}
Пример #11
0
////////
// main() has all the OpenVX application code for this exercise.
// Command-line usage:
//   % solution_exercise2 [<video-sequence>|<camera-device-number>]
// When neither video sequence nor camera device number is specified,
// it defaults to the video sequence in "PETS09-S1-L1-View001.avi".
int main( int argc, char * argv[] )
{
    // Get default video sequence when nothing is specified on command-line and
    // instantiate OpenCV GUI module for reading input RGB images and displaying
    // the image with OpenVX results.
    const char * video_sequence = argv[1];
    CGuiModule gui( video_sequence );

    // Try to grab the first video frame from the sequence using cv::VideoCapture
    // and check if a video frame is available.
    if( !gui.Grab() )
    {
        printf( "ERROR: input has no video\n" );
        return 1;
    }

    ////////
    // Set the application configuration parameters. Note that input video
    // sequence is an 8-bit RGB image with dimensions given by gui.GetWidth()
    // and gui.GetHeight(). The parameters for the Harris corners algorithm are:
    //   max_keypoint_count      - maximum number of keypoints to track
    //   harris_strength_thresh  - minimum threshold score to keep a corner
    //                             (computed using the normalized Sobel kernel)
    //   harris_min_distance     - radial L2 distance for non-max suppression
    //   harris_k_sensitivity    - sensitivity threshold k from the Harris-Stephens
    //   harris_gradient_size    - window size for gradient computation
    //   harris_block_size       - block window size used to compute the
    //                             Harris corner score
    //   lk_pyramid_levels       - number of pyramid levels for LK optical flow
    //   lk_termination          - can be VX_TERM_CRITERIA_ITERATIONS or
    //                               VX_TERM_CRITERIA_EPSILON or
    //                               VX_TERM_CRITERIA_BOTH
    //   lk_epsilon              - error for terminating the algorithm
    //   lk_num_iterations       - number of iterations
    //   lk_use_initial_estimate - turn on/off use of initial estimates
    //   lk_window_dimension     - size of window on which to perform the algorithm
    vx_uint32  width                   = gui.GetWidth();
    vx_uint32  height                  = gui.GetHeight();
    vx_size    max_keypoint_count      = 10000;
    vx_float32 harris_strength_thresh  = 0.0005f;
    vx_float32 harris_min_distance     = 5.0f;
    vx_float32 harris_k_sensitivity    = 0.04f;
    vx_int32   harris_gradient_size    = 3;
    vx_int32   harris_block_size       = 3;
    vx_uint32  lk_pyramid_levels       = 6;
    vx_float32 lk_pyramid_scale        = VX_SCALE_PYRAMID_HALF;
    vx_enum    lk_termination          = VX_TERM_CRITERIA_BOTH;
    vx_float32 lk_epsilon              = 0.01f;
    vx_uint32  lk_num_iterations       = 5;
    vx_bool    lk_use_initial_estimate = vx_false_e;
    vx_uint32  lk_window_dimension     = 6;

    ////////
    // Create the OpenVX context and make sure the returned context is valid and
    // register the log_callback to receive messages from OpenVX framework.
    vx_context context = vxCreateContext();
    ERROR_CHECK_OBJECT( context );
    vxRegisterLogCallback( context, log_callback, vx_false_e );

    ////////
    // Create OpenVX image object for input RGB image.
    vx_image input_rgb_image = vxCreateImage( context, width, height, VX_DF_IMAGE_RGB );
    ERROR_CHECK_OBJECT( input_rgb_image );

    ////////********
    // OpenVX optical flow functionality requires pyramids of the current input
    // image and the previous image. It also requires keypoints that correspond
    // to the previous pyramid and will output updated keypoints into
    // another keypoint array. To be able to toggle between the current and
    // the previous buffers, you need to use OpenVX delay objects and vxAgeDelay().
    // Create OpenVX pyramid and array object exemplars and create OpenVX delay
    // objects for both to hold two of each. Note that the exemplar objects are not
    // needed once the delay objects are created.
    //
    // TODO STEP 01:********
    //   1. Use vxCreatePyramid API to create a pyramid exemplar with the
    //      same dimensions as the input image, VX_DF_IMAGE_U8 as image format,
    //      lk_pyramid_levels as levels, and lk_pyramid_scale as scale.
    //      We gave code for this in comments.
    //   2. Use vxCreateArray API to create an array exemplar with
    //      keypoint data type with num_keypoint_count as capacity.
    //      You need to add missing parameters to code in comments.
    //   3. Use vxCreateDelay API to create delay objects for pyramid and
    //      keypoint array using the exemplars created using the two steps above.
    //      Use 2 delay slots for both of the delay objects.
    //      We gave code for one in comments; do similar for the other.
    //   4. Release the pyramid and keypoint array exemplar objects.
    //      We gave code for one in comments; do similar for the other.
    //   5. Use ERROR_CHECK_OBJECT/STATUS macros for proper error checking.
    //      We gave few error checks; do similar for the others.
//    vx_pyramid pyramidExemplar = vxCreatePyramid( context, lk_pyramid_levels,
//                                                  lk_pyramid_scale, width, height, VX_DF_IMAGE_U8 );
//    ERROR_CHECK_OBJECT( pyramidExemplar );
//    vx_delay pyramidDelay   = vxCreateDelay( context, ( vx_reference )pyramidExemplar, 2 );
//    ERROR_CHECK_OBJECT( pyramidDelay );
//    ERROR_CHECK_STATUS( vxReleasePyramid( &pyramidExemplar ) );
//    vx_array keypointsExemplar = vxCreateArray( /* Fill in parameters */ );
//    vx_delay keypointsDelay = vxCreateDelay( /* Fill in parameters */ );


    ////////********
    // An object from a delay slot can be accessed using vxGetReferenceFromDelay API.
    // You need to use index = 0 for the current object and index = -1 for the previous object.
    //
    // TODO STEP 02:********
    //   1. Use vxGetReferenceFromDelay API to get the current and previous
    //      pyramid objects from pyramid delay object. Note that you need
    //      to typecast the vx_reference object to vx_pyramid.
    //      We gave code for one in comments; do similar for the other.
    //   2. Similarly, get the current and previous keypoint array objects from
    //      the keypoint delay object.
    //      We gave code for one in comments; do similar for the other.
    //   3. Use ERROR_CHECK_OBJECT for proper error checking.
    //      We gave one error check; do similar for the others.
//    vx_pyramid currentPyramid  = ( vx_pyramid ) vxGetReferenceFromDelay( pyramidDelay, 0 );
//    vx_pyramid previousPyramid = ( vx_pyramid ) vxGetReferenceFromDelay( /* Fill in parameters */ );
//    vx_array currentKeypoints  = ( vx_array )   vxGetReferenceFromDelay( /* Fill in parameters */ );
//    vx_array previousKeypoints = ( vx_array )   vxGetReferenceFromDelay( keypointsDelay, -1 );
//    ERROR_CHECK_OBJECT( currentPyramid );


    ////////********
    // Harris and optical flow algorithms require their own graph objects.
    // The Harris graph needs to extract gray scale image out of input RGB,
    // compute an initial set of keypoints, and compute an initial pyramid for use
    // by the optical flow graph.
    //
    // TODO STEP 03:********
    //   1. Create two graph objects: one for the Harris corner detector and
    //      the other for feature tracking using optical flow using the
    //      vxCreateGraph API.
    //      We gave code for one graph; do similar for the other.
    //   2. Use ERROR_CHECK_OBJECT to check the objects.
    //      We gave one error check; do similar for the other.
//    vx_graph graphHarris = vxCreateGraph( context );
//    vx_graph graphTrack  = /* Fill in here */;
//    ERROR_CHECK_OBJECT( graphHarris );


    ////////********
    // Harris and pyramid computation expect input to be an 8-bit image.
    // Given that input is an RGB image, it is best to extract a gray image
    // from RGB image, which requires two steps:
    //   - perform RGB to IYUV color conversion
    //   - extract Y channel from IYUV image
    // This requires two intermediate OpenVX image objects. Since you don't
    // need to access these objects from the application, they can be virtual
    // objects that can be created using the vxCreateVirtualImage API.
    //
    // TODO STEP 04:********
    //   1. Create an IYUV image and a U8 image (for Y channel) with the same
    //      dimensions as the input RGB image. Note that the image formats for
    //      IYUV and U8 images are VX_DF_IMAGE_IYUV and VX_DF_IMAGE_U8.
    //      Note that virtual objects are specific to a graph, so you
    //      need to create two sets, one for each graph.
    //      We gave one fully in comments and you need to fill in missing
    //      parameters for the others.
    //   2. Use ERROR_CHECK_OBJECT to check the objects.
    //      We gave one error check in comments; do similar for others.
//    vx_image harris_yuv_image       = vxCreateVirtualImage( graphHarris, width, height, VX_DF_IMAGE_IYUV );
//    vx_image harris_luma_image      = vxCreateVirtualImage( graphHarris, /* Fill in parameters */ );
//    vx_image opticalflow_yuv_image  = vxCreateVirtualImage( graphTrack,  /* Fill in parameters */ );
//    vx_image opticalflow_luma_image = vxCreateVirtualImage( /* Fill in parameters */ );
//    ERROR_CHECK_OBJECT( harris_yuv_image );


    ////////********
    // The Harris corner detector and optical flow nodes (see "VX/vx_nodes.h")
    // take strength_thresh, min_distance, sensitivity, epsilon,
    // num_iterations, and use_initial_estimate parameters as scalar
    // data objects. So, you need to create scalar objects with the corresponding
    // configuration parameters.
    //
    // TODO STEP 05:********
    //   1. Create scalar data objects of VX_TYPE_FLOAT32 for strength_thresh,
    //      min_distance, sensitivity, and epsilon. Set their
    //      initial values to harris_strength_thresh, harris_min_distance,
    //      harris_k_sensitivity, and lk_epsilon.
    //      We gave code full code for one scalar in comments; fill in
    //      missing arguments for other ones.
    //   2. Similarly, create scalar objects for num_iterations and
    //      use_initial_estimate with initial values: lk_num_iterations and
    //      lk_use_initial_estimate. Make sure to use proper data types for
    //      these parameters.
    //      We gave code full code for one scalar in comments; fill in
    //      missing arguments for the other.
    //   3. Use ERROR_CHECK_OBJECT to check proper creation of objects.
    //      We gave the error check for one scalar; do similar for other 5 scalars.
//    vx_scalar strength_thresh      = NULL; // vxCreateScalar( context, VX_TYPE_FLOAT32, &harris_strength_thresh );
//    vx_scalar min_distance         = NULL; // vxCreateScalar( context, /* Fill in parameters */ );
//    vx_scalar sensitivity          = NULL; // vxCreateScalar( /* Fill in parameters */ );
//    vx_scalar epsilon              = NULL; // vxCreateScalar( /* Fill in parameters */ );
//    vx_scalar num_iterations       = NULL; // vxCreateScalar( context, VX_TYPE_UINT32,  /* Fill in parameter */ );
//    vx_scalar use_initial_estimate = NULL; // vxCreateScalar( context, VX_TYPE_BOOL,    &lk_use_initial_estimate );
//    ERROR_CHECK_OBJECT( strength_thresh );


    ////////********
    // Now all the objects have been created for building the graphs.
    // First, build a graph that performs Harris corner detection and initial pyramid computation.
    // See "VX/vx_nodes.h" for APIs how to add nodes into a graph.
    //
    // TODO STEP 06:********
    //   1. Use vxColorConvertNode and vxChannelExtractNode APIs to get gray
    //      scale image for Harris and Pyramid computation from the input
    //      RGB image. Add these nodes into Harris graph.
    //      We gave code in comments with a missing parameter for you to fill in.
    //   2. Use vxGaussianPyramidNode API to add pyramid computation node.
    //      You need to use the current pyramid from the pyramid delay object.
    //      We gave code in comments with a missing parameter for you to fill in.
    //   3. Use vxHarrisCornersNode API to add a Harris corners node.
    //      You need to use the current keypoints from keypoints delay object.
    //      We gave code in comments with few missing parameters for you to fill in.
    //   4. Use ERROR_CHECK_OBJECT to check proper creation of objects.
    //   5. Release node and virtual objects immediately since the graph
    //      retains references to them.
    //   6. Call vxVerifyGraph to check for any errors in the graph.
    //      Fill in missing parameter in commented code.
//    vx_node nodesHarris[] =
//    {
//        vxColorConvertNode( graphHarris, input_rgb_image, harris_yuv_image ),
//        vxChannelExtractNode( graphHarris, /* Fill in parameter */, VX_CHANNEL_Y, harris_luma_image ),
//        vxGaussianPyramidNode( graphHarris, /* Fill in parameter */, currentPyramid ),
//        vxHarrisCornersNode( graphHarris, /* Fill in missing parameters */, currentKeypoints, NULL )
//    };
//    for( vx_size i = 0; i < sizeof( nodesHarris ) / sizeof( nodesHarris[0] ); i++ )
//    {
//        ERROR_CHECK_OBJECT( nodesHarris[i] );
//        ERROR_CHECK_STATUS( vxReleaseNode( &nodesHarris[i] ) );
//    }
//    ERROR_CHECK_STATUS( vxReleaseImage( &harris_yuv_image ) );
//    ERROR_CHECK_STATUS( vxReleaseImage( &harris_luma_image ) );
//    ERROR_CHECK_STATUS( vxVerifyGraph( /* Fill in parameter */ ) );


    ////////********
    // Now, build a graph that performs pyramid computation and feature
    // tracking using optical flow.
    //
    // TODO STEP 07:********
    //   1. Use vxColorConvertNode and vxChannelExtractNode APIs to get a gray
    //      scale image for Harris and Pyramid computation from the input
    //      RGB image. Add these nodes into Harris graph.
    //      We gave the code in comments for color convert node; do similar
    //      one for the channel extract node.
    //   2. Use vxGaussianPyramidNode API to add pyramid computation node.
    //      You need to use the current pyramid from the pyramid delay object.
    //      Most of the code is given in the comments; fill in the missing parameter.
    //   3. Use vxOpticalFlowPyrLKNode API to add an optical flow node. You need to
    //      use the current and previous keypoints from the keypoints delay object.
    //      Fill in the missing parameters in commented code.
    //   4. Use ERROR_CHECK_OBJECT to check proper creation of objects.
    //   5. Release node and virtual objects immediately since the graph
    //      retains references to them.
    //   6. Call vxVerifyGraph to check for any errors in the graph.
    //      Fill in the missing parameter in commented code.
//    vx_node nodesTrack[] =
//    {
//        vxColorConvertNode( graphTrack, input_rgb_image, opticalflow_yuv_image ),
//        vxChannelExtractNode( graphTrack, /* Fill in parameters */ ),
//        vxGaussianPyramidNode( graphTrack, /* Fill in parameter */, currentPyramid ),
//        vxOpticalFlowPyrLKNode( graphTrack, /* Fill in parameters */ )
//    };
//    for( vx_size i = 0; i < sizeof( nodesTrack ) / sizeof( nodesTrack[0] ); i++ )
//    {
//        ERROR_CHECK_OBJECT( nodesTrack[i] );
//        ERROR_CHECK_STATUS( vxReleaseNode( &nodesTrack[i] ) );
//    }
//    ERROR_CHECK_STATUS( vxReleaseImage( &opticalflow_yuv_image ) );
//    ERROR_CHECK_STATUS( vxReleaseImage( &opticalflow_luma_image ) );
//    ERROR_CHECK_STATUS( vxVerifyGraph( /* Fill in parameter */ ) );


    ////////
    // Process the video sequence frame by frame until the end of sequence or aborted.
    for( int frame_index = 0; !gui.AbortRequested(); frame_index++ )
    {
        ////////
        // Copy the input RGB frame from OpenCV to OpenVX.
        // In order to do this, you need to use vxAccessImagePatch and vxCommitImagePatch APIs.
        // See "VX/vx_api.h" for the description of these APIs.
        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.stride_x   = 3;
        cv_rgb_image_layout.stride_y   = gui.GetStride();
        vx_uint8 * cv_rgb_image_buffer = gui.GetBuffer();
        ERROR_CHECK_STATUS( vxAccessImagePatch( input_rgb_image, &cv_rgb_image_region, 0,
                                                &cv_rgb_image_layout, ( void ** )&cv_rgb_image_buffer, VX_WRITE_ONLY ) );
        ERROR_CHECK_STATUS( vxCommitImagePatch( input_rgb_image, &cv_rgb_image_region, 0,
                                                &cv_rgb_image_layout, cv_rgb_image_buffer ) );

        ////////********
        // Now that input RGB image is ready, just run a graph.
        // Run Harris at the beginning to initialize the previous keypoints.
        //
        // TODO STEP 08:********
        //   1. Run a graph using vxProcessGraph API. Select Harris graph
        //      if the frame_index == 0 (i.e., the first frame of the video
        //      sequence), otherwise, select the feature tracking graph.
        //   2. Use ERROR_CHECK_STATUS for error checking.



        ////////********
        // To mark the keypoints in display, you need to access the output
        // keypoint array and draw each item on the output window using gui.DrawArrow().
        //
        // TODO STEP 09:********
        //   1. Use vxGetReferenceFromDelay API to get the current and previous
        //      keypoints array objects from the keypoints delay object.
        //      Make sure to typecast the vx_reference object to vx_array.
        //      We gave one for the previous previous keypoint array in comments;
        //      do a similar one for the current keypoint array.
        //   2. OpenVX array object has an attribute that keeps the current
        //      number of items in the array. The name of the attribute is
        //      VX_ARRAY_ATTRIBUTE_NUMITEMS and its value is of type vx_size.
        //      Use vxQueryArray API to get number of keypoints in the
        //      current keypoint array data object, representing number of
        //      corners detected in the input RGB image.
        //      IMPORTANT: Read number of items into "num_corners"
        //      because this variable is displayed by code segment below.
        //      We gave most part of this statement in comment; just fill in the
        //      missing parameter.
        //   3. The data items in output keypoint array are of type
        //      vx_keypoint_t (see "VX/vx_types.h"). To access the array
        //      buffer, use vxAccessArrayRange with start index = 0,
        //      end index = number of items in the array, and usage mode =
        //      VX_READ_ONLY. Note that the stride returned by this access
        //      call is not guaranteed to be sizeof(vx_keypoint_t).
        //      Also make sure that num_corners is > 0, because
        //      vxAccessArrayRange expects end index > 0.
        //      We gave the code for previous keypoint array in comment;
        //      do similar one for the current keypoint array.
        //   4. For each item in the keypoint buffer, use vxArrayItem to
        //      access an individual keypoint and draw a marker at (x,y)
        //      using gui.DrawArrow() if tracking_status field of keypoint
        //      is non-zero. Also count number of keypoints with
        //      non-zero tracking_status into "num_tracking" variable.
        //      We gave most of the code; fill in the missing parameters and uncomment.
        //   5. Hand the control of output keypoint buffer over back to
        //      OpenVX framework by calling vxCommitArrayRange API.
        //      We gave the code for previous keypoint array in comment;
        //      do similar one for the current keypoint array.
        //   6. Use ERROR_CHECK_STATUS for error checking.
        vx_size num_corners = 0, num_tracking = 0;
//        previousKeypoints = ( vx_array )vxGetReferenceFromDelay( keypointsDelay, -1 );
//        currentKeypoints  = ( vx_array )vxGetReferenceFromDelay( /* Fill in parameters */ );
//        ERROR_CHECK_OBJECT( currentKeypoints );
//        ERROR_CHECK_OBJECT( previousKeypoints );
//        ERROR_CHECK_STATUS( vxQueryArray( previousKeypoints, /* Fill in parameter */, &num_corners, sizeof( num_corners ) ) );
        if( num_corners > 0 )
        {
            vx_size kp_old_stride, kp_new_stride;
            vx_keypoint_t * kp_old_buf = NULL, * kp_new_buf = NULL;
//            ERROR_CHECK_STATUS( vxAccessArrayRange( previousKeypoints, 0, num_corners,
//                                                    &kp_old_stride, ( void ** ) &kp_old_buf, VX_READ_ONLY ) );
//            ERROR_CHECK_STATUS( vxAccessArrayRange( /* Fill in parameters */ );
            for( vx_size i = 0; i < num_corners; i++ )
            {
//                vx_keypoint_t * kp_old = &vxArrayItem( vx_keypoint_t, kp_old_buf, i, kp_old_stride );
//                vx_keypoint_t * kp_new = &vxArrayItem( /* Fill in parameters */ );
//                if( kp_new->tracking_status )
//                {
//                    num_tracking++;
//                    gui.DrawArrow( kp_old->x, kp_old->y, kp_new->x, kp_new->y );
//                }
            }
//            ERROR_CHECK_STATUS( vxCommitArrayRange( previousKeypoints, 0, num_corners, kp_old_buf ) );
//            ERROR_CHECK_STATUS( vxCommitArrayRange( /* Fill in parameters */ ) );
        }


        ////////********
        // Flip the current and previous pyramid and keypoints in the delay objects.
        //
        // TODO STEP 10:********
        //   1. Use vxAgeDelay API to flip the current and previous buffers in delay objects.
        //      You need to call vxAgeDelay for both two delay objects.
        //   2. Use ERROR_CHECK_STATUS for error checking.
//        ERROR_CHECK_STATUS( vxAgeDelay( /* Fill in parameter */ ) );
//        ERROR_CHECK_STATUS( vxAgeDelay( /* Fill in parameter */ ) );


        ////////
        // Display the results and grab the next input RGB frame for the next iteration.
        char text[128];
        sprintf( text, "Keyboard ESC/Q-Quit SPACE-Pause [FRAME %d]", frame_index );
        gui.DrawText( 0, 16, text );
        sprintf( text, "Number of Corners: %d [tracking %d]", ( int )num_corners, ( int )num_tracking );
        gui.DrawText( 0, 36, text );
        gui.Show();
        if( !gui.Grab() )
        {
            // Terminate the processing loop if the end of sequence is detected.
            gui.WaitForKey();
            break;
        }
    }

    ////////********
    // Query graph performance using VX_GRAPH_ATTRIBUTE_PERFORMANCE and print timing
    // in milliseconds. Note that time units of vx_perf_t fields are nanoseconds.
    //
    // TODO STEP 11:********
    //   1. Use vxQueryGraph API with VX_GRAPH_ATTRIBUTE_PERFORMANCE to query graph performance.
    //      We gave the attribute query for one graph in comments. Do the same for the second graph.
    //   2. Print the average and min execution times in milliseconds. Use the printf in comments.
//    vx_perf_t perfHarris = { 0 }, perfTrack = { 0 };
//    ERROR_CHECK_STATUS( vxQueryGraph( graphHarris, VX_GRAPH_ATTRIBUTE_PERFORMANCE, &perfHarris, sizeof( perfHarris ) ) );
//    ERROR_CHECK_STATUS( vxQueryGraph( /* Fill in parameters here for get performance of the other graph */ );
//    printf( "GraphName NumFrames Avg(ms) Min(ms)\n"
//            "Harris    %9d %7.3f %7.3f\n"
//            "Track     %9d %7.3f %7.3f\n",
//            ( int )perfHarris.num, ( float )perfHarris.avg * 1e-6f, ( float )perfHarris.min * 1e-6f,
//            ( int )perfTrack.num,  ( float )perfTrack.avg  * 1e-6f, ( float )perfTrack.min  * 1e-6f );


    ////////********
    // Release all the OpenVX objects created in this exercise, and make the context as the last one to release.
    // To release an OpenVX object, you need to call vxRelease<Object> API which takes a pointer to the object.
    // If the release operation is successful, the OpenVX framework will reset the object to NULL.
    //
    // TODO STEP 12:********
    //   1. For releasing all other objects use vxRelease<Object> APIs.
    //      You have to release 2 graph objects, 1 image object, 2 delay objects,
    //      6 scalar objects, and 1 context object.
    //   2. Use ERROR_CHECK_STATUS for error checking.
//    ERROR_CHECK_STATUS( vxReleaseContext( &context ) );


    return 0;
}
Пример #12
0
// nodeless version of the Convolve kernel
vx_status vxConvolve(vx_image src, vx_convolution conv, vx_image dst, vx_border_mode_t *bordermode)
{
    vx_int32 y, x, i;
    void *src_base = NULL;
    void *dst_base = NULL;
    vx_imagepatch_addressing_t src_addr, dst_addr;
    vx_rectangle_t rect;
    vx_size conv_width, conv_height;
    vx_int32 conv_radius_x, conv_radius_y;
    vx_int16 conv_mat[C_MAX_CONVOLUTION_DIM * C_MAX_CONVOLUTION_DIM] = {0};
    vx_int32 sum = 0, value = 0;
    vx_uint32 scale = 1;
    vx_df_image src_format = 0;
    vx_df_image dst_format = 0;
    vx_status status  = VX_SUCCESS;
    vx_int32 low_x, low_y, high_x, high_y;

    status |= vxQueryImage(src, VX_IMAGE_ATTRIBUTE_FORMAT, &src_format, sizeof(src_format));
    status |= vxQueryImage(dst, VX_IMAGE_ATTRIBUTE_FORMAT, &dst_format, sizeof(dst_format));
    status |= vxQueryConvolution(conv, VX_CONVOLUTION_ATTRIBUTE_COLUMNS, &conv_width, sizeof(conv_width));
    status |= vxQueryConvolution(conv, VX_CONVOLUTION_ATTRIBUTE_ROWS, &conv_height, sizeof(conv_height));
    status |= vxQueryConvolution(conv, VX_CONVOLUTION_ATTRIBUTE_SCALE, &scale, sizeof(scale));
    conv_radius_x = (vx_int32)conv_width / 2;
    conv_radius_y = (vx_int32)conv_height / 2;
    status |= vxReadConvolutionCoefficients(conv, conv_mat);
    status |= vxGetValidRegionImage(src, &rect);
    status |= vxAccessImagePatch(src, &rect, 0, &src_addr, &src_base, VX_READ_ONLY);
    status |= vxAccessImagePatch(dst, &rect, 0, &dst_addr, &dst_base, VX_WRITE_ONLY);

    if (bordermode->mode == VX_BORDER_MODE_UNDEFINED)
    {
        low_x = conv_radius_x;
        high_x = ((src_addr.dim_x >= (vx_uint32)conv_radius_x) ? src_addr.dim_x - conv_radius_x : 0);
        low_y = conv_radius_y;
        high_y = ((src_addr.dim_y >= (vx_uint32)conv_radius_y) ? src_addr.dim_y - conv_radius_y : 0);
        vxAlterRectangle(&rect, conv_radius_x, conv_radius_y, -conv_radius_x, -conv_radius_y);
    }
    else
    {
        low_x = 0;
        high_x = src_addr.dim_x;
        low_y = 0;
        high_y = src_addr.dim_y;
    }

    for (y = low_y; y < high_y; ++y)
    {
        for (x = low_x; x < high_x; ++x)
        {
            sum = 0;

            if (src_format == VX_DF_IMAGE_U8)
            {
                vx_uint8 slice[C_MAX_CONVOLUTION_DIM * C_MAX_CONVOLUTION_DIM] = {0};

                vxReadRectangle(src_base, &src_addr, bordermode, src_format, x, y, conv_radius_x, conv_radius_y, slice);

                for (i = 0; i < conv_width * conv_height; ++i)
                    sum += conv_mat[conv_width * conv_height - 1 - i] * slice[i];
            }
            else if (src_format == VX_DF_IMAGE_S16)
            {
                vx_int16 slice[C_MAX_CONVOLUTION_DIM * C_MAX_CONVOLUTION_DIM] = {0};

                vxReadRectangle(src_base, &src_addr, bordermode, src_format, x, y, conv_radius_x, conv_radius_y, slice);

                for (i = 0; i < conv_width * conv_height; ++i)
                    sum += conv_mat[conv_width * conv_height - 1 - i] * slice[i];
            }

            value = sum / (vx_int32) scale;

            if (dst_format == VX_DF_IMAGE_U8)
            {
                vx_uint8 *dstp = vxFormatImagePatchAddress2d(dst_base, x, y, &dst_addr);
                if (value < 0) *dstp = 0;
                else if (value > UINT8_MAX) *dstp = UINT8_MAX;
                else *dstp = value;
            }
            else if (dst_format == VX_DF_IMAGE_S16)
            {
                vx_int16 *dstp = vxFormatImagePatchAddress2d(dst_base, x, y, &dst_addr);
                if (value < INT16_MIN) *dstp = INT16_MIN;
                else if (value > INT16_MAX) *dstp = INT16_MAX;
                else *dstp = value;
            }
        }
    }

    status |= vxCommitImagePatch(src, NULL, 0, &src_addr, src_base);
    status |= vxCommitImagePatch(dst, &rect, 0, &dst_addr, dst_base);

    return status;
}
Пример #13
0
static vx_status vxChannelCombineKernel(vx_node node, vx_reference *parameters, vx_uint32 num)
{
    vx_status status = VX_FAILURE;
    if (num == 5)
    {
        vx_image inputs[4] = {
            (vx_image)parameters[0],
            (vx_image)parameters[1],
            (vx_image)parameters[2],
            (vx_image)parameters[3],
        };
        vx_image output = (vx_image)parameters[4];
        vx_fourcc format = 0;
        vx_rectangle rect;
        vxQueryImage(output, VX_IMAGE_ATTRIBUTE_FORMAT, &format, sizeof(format));
        rect = vxGetValidRegionImage(inputs[0]);
        if ((format == FOURCC_RGB) || (format == FOURCC_RGBX))
        {
            /* write all the channels back out in interleaved format */
            vx_imagepatch_addressing_t src_addrs[4];
            vx_imagepatch_addressing_t dst_addr;
            void *base_src_ptrs[4] = {NULL, NULL, NULL, NULL};
            void *base_dst_ptr = NULL;
            uint32_t x, y, p;
            uint32_t numplanes = 3;

            if (format == FOURCC_RGBX)
            {
                numplanes = 4;
            }

            // get the planes
            for (p = 0; p < numplanes; p++)
            {
                vxAccessImagePatch(inputs[p], rect, 0, &src_addrs[p], &base_src_ptrs[p]);
            }
            vxAccessImagePatch(output, rect, 0, &dst_addr, &base_dst_ptr);
            for (y = 0; y < dst_addr.dim_y; y+=dst_addr.step_y)
            {
                for (x = 0; x < dst_addr.dim_x; x+=dst_addr.step_x)
                {
                    uint8_t *planes[4] = {
                        vxFormatImagePatchAddress2d(base_src_ptrs[0], x, y, &src_addrs[0]),
                        vxFormatImagePatchAddress2d(base_src_ptrs[1], x, y, &src_addrs[1]),
                        vxFormatImagePatchAddress2d(base_src_ptrs[2], x, y, &src_addrs[2]),
                        NULL,
                    };
                    uint8_t *dst = vxFormatImagePatchAddress2d(base_dst_ptr, x, y, &dst_addr);
                    dst[0] = planes[0][0];
                    dst[1] = planes[1][0];
                    dst[2] = planes[2][0];
                    if (format == FOURCC_RGBX)
                    {
                        planes[3] = vxFormatImagePatchAddress2d(base_src_ptrs[3], x, y, &src_addrs[3]);
                        dst[3] = planes[3][0];
                    }
                }
            }
            // write the data back
            vxCommitImagePatch(output, rect, 0, &dst_addr, base_dst_ptr);
            // release the planes
            for (p = 0; p < numplanes; p++)
            {
                vxCommitImagePatch(inputs[p], 0, 0, &src_addrs[p], &base_src_ptrs[p]);
            }
        }
        else if (format == FOURCC_YUV4)
        {
            /* write all the channels back out in the planar format */
            vx_imagepatch_addressing_t src_addrs[3];
            vx_imagepatch_addressing_t dst_addrs[3];
            void *base_src_ptrs[3] = {NULL, NULL, NULL};
            void *base_dst_ptrs[3] = {NULL, NULL, NULL};
            uint32_t x, y, p;

            // get the planes
            for (p = 0; p < 3; p++)
            {
                vxAccessImagePatch(inputs[p], rect, 0, &src_addrs[p], &base_src_ptrs[p]);
                vxAccessImagePatch(output, rect, 0, &dst_addrs[p], &base_dst_ptrs[p]);
            }

            for (y = 0; y < dst_addrs[0].dim_y; y+=dst_addrs[0].step_y)
            {
                for (x = 0; x < dst_addrs[0].dim_x; x+=dst_addrs[0].step_x)
                {
                    uint8_t *planes[3] = {
                        vxFormatImagePatchAddress2d(base_src_ptrs[0], x, y, &src_addrs[0]),
                        vxFormatImagePatchAddress2d(base_src_ptrs[1], x, y, &src_addrs[1]),
                        vxFormatImagePatchAddress2d(base_src_ptrs[2], x, y, &src_addrs[2]),
                    };
                    uint8_t *dsts[3] = {
                        vxFormatImagePatchAddress2d(base_dst_ptrs[0], x, y, &dst_addrs[0]),
                        vxFormatImagePatchAddress2d(base_dst_ptrs[0], x, y, &dst_addrs[0]),
                        vxFormatImagePatchAddress2d(base_dst_ptrs[0], x, y, &dst_addrs[0]),
                    };
                    dsts[0][0] = planes[0][0];
                    dsts[1][0] = planes[1][0];
                    dsts[2][0] = planes[2][0];
                }
            }
            // release the planes
            for (p = 0; p < 3; p++)
            {
                // write the data back
                vxCommitImagePatch(output, rect, 0, &dst_addrs[p], base_dst_ptrs[p]);
                // release the input
                vxCommitImagePatch(inputs[p], 0, 0, &src_addrs[p], &base_src_ptrs[p]);
            }
        }
        vxReleaseRectangle(&rect);
        status = VX_SUCCESS;
    }
    else
        status = VX_ERROR_INVALID_PARAMETERS;
    return status;
}
Пример #14
0
static vx_status vxEqualizeHistKernel(vx_node node, vx_reference *parameters, vx_uint32 num)
{
    vx_status status = VX_FAILURE;
    if (num == 2)
    {
        vx_image src = (vx_image)parameters[0];
        vx_image dst = (vx_image)parameters[1];
        vx_uint32 y, x, width = 0, height = 0;
        void *src_base = NULL;
        void *dst_base = NULL;
        vx_imagepatch_addressing_t src_addr, dst_addr;
        vx_rectangle rect;

        status = VX_SUCCESS;
        status |= vxQueryImage(src, VX_IMAGE_ATTRIBUTE_WIDTH, &width, sizeof(width));
        status |= vxQueryImage(src, VX_IMAGE_ATTRIBUTE_HEIGHT, &height, sizeof(height));
        rect = vxCreateRectangle(vxGetContext(node), 0, 0, width, height);
        status |= vxAccessImagePatch(src, rect, 0, &src_addr, &src_base);
        status |= vxAccessImagePatch(dst, rect, 0, &dst_addr, &dst_base);
        if (status == VX_SUCCESS)
        {
            /* for 16-bit support (U16 or S16), the code can be duplicated with NUM_BINS = 65536 and PIXEL = vx_uint16. */
            #define NUM_BINS 256

            /* allocate a fixed-size temp array to store the image histogram & cumulative distribution */
            vx_uint32 hist[NUM_BINS];
            vx_uint32 cdf[NUM_BINS];
            vx_uint32 sum = 0;
            vx_uint32 maxVal = 0;
            vx_float32 scaleFactor = 0.0f;

            /* calculate the distribution (histogram) */
            memset(hist, 0, sizeof(hist));
            for (y = 0; y < height; y++)
            {
                for (x = 0; x < width; x++)
                {
                    vx_uint8 *src_ptr = vxFormatImagePatchAddress2d(src_base, x, y, &src_addr);
                    vx_uint8 pixel = *src_ptr;
                    hist[pixel]++;
                }
            }

            /* calculate the cumulative distribution (summed histogram) */
            for (x = 0; x < NUM_BINS; x++)
            {
                cdf[x] = sum;
                sum += hist[x];
            }

            /* find the scale factor from the max cdf value */
            maxVal = cdf[0];
            for (x = 1; x < NUM_BINS; x++)
            {
                if (maxVal < cdf[x])
                {
                    maxVal = cdf[x];
                }
            }
            scaleFactor = 255.0f / (float)maxVal;
            //printf("* maxVal = %d, scaleFactor = %f\n", maxVal, scaleFactor);

            /* map the src pixel values to the equalized pixel values */
            for (y = 0; y < height; y++)
            {
                for (x = 0; x < width; x++)
                {
                    vx_uint8 *src_ptr = vxFormatImagePatchAddress2d(src_base, x, y, &src_addr);
                    vx_uint8 *dst_ptr = vxFormatImagePatchAddress2d(dst_base, x, y, &dst_addr);
                    vx_uint32 equalized_int = cdf[(*src_ptr)];
                    *dst_ptr = (vx_uint8)(equalized_int * scaleFactor + 0.5f);
                }
            }
        }

        status |= vxCommitImagePatch(src, 0, 0, &src_addr, src_base);
        status |= vxCommitImagePatch(dst, rect, 0, &dst_addr, dst_base);
        vxReleaseRectangle(&rect);
    }
    return status;
}
Пример #15
0
static vx_status vxHistogramKernel(vx_node node, vx_reference *parameters, vx_uint32 num)
{
    vx_status status = VX_FAILURE;
    if (num == 2)
    {
        vx_image src_image = (vx_image)parameters[0];
        vx_distribution dist = (vx_scalar)parameters[1];
        vx_rectangle src_rect;
        vx_imagepatch_addressing_t src_addr;
        void *src_base = NULL, *dist_ptr = NULL;
        vx_fourcc format = 0;
        vx_uint32 y = 0, x = 0;
        vx_uint32 offset = 0, range = 0, numBins = 0, window_size = 0;

        vxQueryImage(src_image, VX_IMAGE_ATTRIBUTE_FORMAT, &format, sizeof(format));
        vxQueryDistribution(dist, VX_DISTRIBUTION_ATTRIBUTE_BINS, &numBins, sizeof(numBins));
        vxQueryDistribution(dist, VX_DISTRIBUTION_ATTRIBUTE_RANGE, &range, sizeof(range));
        vxQueryDistribution(dist, VX_DISTRIBUTION_ATTRIBUTE_OFFSET, &offset, sizeof(offset));
        vxQueryDistribution(dist, VX_DISTRIBUTION_ATTRIBUTE_WINDOW, &window_size, sizeof(window_size));
        src_rect = vxGetValidRegionImage(src_image);
        status = VX_SUCCESS;
        status |= vxAccessImagePatch(src_image, src_rect, 0, &src_addr, &src_base);
        status |= vxAccessDistribution(dist, &dist_ptr);
        printf("distribution:%p bins:%u off:%u ws:%u range:%u\n", dist_ptr, numBins, offset, window_size, range);
        if (status == VX_SUCCESS)
        {
            vx_int32 *dist_tmp = dist_ptr;

            /* clear the distribution */
            for (x = 0; x < numBins; x++)
            {
                dist_tmp[x] = 0;
            }

            for (y = 0; y < src_addr.dim_y; y++)
            {
                for (x = 0; x < src_addr.dim_x; x++)
                {
                    if (format == FOURCC_U8)
                    {
                        vx_uint8 *src_ptr = vxFormatImagePatchAddress2d(src_base, x, y, &src_addr);
                        vx_uint8 pixel = *src_ptr;
                        if ((offset <= (vx_size)pixel) && ((vx_size)pixel < (offset+range)))
                        {
                            vx_size index = (pixel - (vx_uint16)offset) / window_size;
                            dist_tmp[index]++;
                        }
                    }
                    else if (format == FOURCC_U16)
                    {
                        vx_uint16 *src_ptr = vxFormatImagePatchAddress2d(src_base, x, y, &src_addr);
                        vx_uint16 pixel = *src_ptr;
                        if ((offset <= (vx_size)pixel) && ((vx_size)pixel < (offset+range)))
                        {
                            vx_size index = (pixel - (vx_uint16)offset) / window_size;
                            dist_tmp[index]++;
                        }
                    }
                }
            }
        }
        status |= vxCommitDistribution(dist, dist_ptr);
        status |= vxCommitImagePatch(src_image, 0, 0, &src_addr, src_base);
        vxReleaseParameter(&src_rect);
    }
    return status;
}
Пример #16
0
vx_status vxFReadImage(vx_array file, vx_image output)
{
    vx_char *filename = NULL;
    vx_size filename_stride = 0;
    vx_uint8 *src = NULL;
    vx_uint32 p = 0u, y = 0u;
    vx_size planes = 0u;
    vx_imagepatch_addressing_t addr = {0};
    vx_df_image format = VX_DF_IMAGE_VIRT;
    FILE *fp = NULL;
    vx_char tmp[VX_MAX_FILE_NAME] = {0};
    vx_char *ext = NULL;
    vx_rectangle_t rect;
    vx_uint32 width = 0, height = 0;

    vx_status status = vxAccessArrayRange(file, 0, VX_MAX_FILE_NAME, &filename_stride, (void **)&filename, VX_READ_ONLY);
    if (status != VX_SUCCESS || filename_stride != sizeof(vx_char))
    {
        vxAddLogEntry((vx_reference)file, VX_FAILURE, "Incorrect array "VX_FMT_REF"\n", file);
        return VX_FAILURE;
    }
    fp = fopen(filename, "rb");
    if (fp == NULL) {
        vxAddLogEntry((vx_reference)file, VX_FAILURE, "Failed to open file %s\n",filename);
        return VX_FAILURE;
    }

    vxQueryImage(output, VX_IMAGE_PLANES, &planes, sizeof(planes));
    vxQueryImage(output, VX_IMAGE_FORMAT, &format, sizeof(format));

    ext = strrchr(filename, '.');
    if (ext && (strcmp(ext, ".pgm") == 0 || strcmp(ext, ".PGM") == 0))
    {
        FGETS(tmp, fp); // PX
        FGETS(tmp, fp); // comment
        FGETS(tmp, fp); // W H
        sscanf(tmp, "%u %u", &width, &height);
        FGETS(tmp, fp); // BPP
        // ! \todo double check image size?
    }
    else if (ext && (strcmp(ext, ".yuv") == 0 ||
                     strcmp(ext, ".rgb") == 0 ||
                     strcmp(ext, ".bw") == 0))
    {
        sscanf(filename, "%*[^_]_%ux%u_%*s", &width, &height);
    }

    rect.start_x = rect.start_y = 0;
    rect.end_x = width;
    rect.end_y = height;

    for (p = 0; p < planes; p++)
    {
        status = vxAccessImagePatch(output, &rect, p, &addr, (void **)&src, VX_WRITE_ONLY);
        if (status == VX_SUCCESS)
        {
            for (y = 0; y < addr.dim_y; y+=addr.step_y)
            {
                vx_uint8 *srcp = vxFormatImagePatchAddress2d(src, 0, y, &addr);
                vx_size len = ((addr.dim_x * addr.scale_x)/VX_SCALE_UNITY);
                vx_size rlen = fread(srcp, addr.stride_x, len, fp);
                if (rlen != len)
                {
                    status = VX_FAILURE;
                    break;
                }
            }
            if (status == VX_SUCCESS)
            {
                status = vxCommitImagePatch(output, &rect, p, &addr, src);
            }
            if (status != VX_SUCCESS)
            {
                break;
            }
        }
        /* src pointer should be made NULL , otherwise the first plane data gets over written. */
        src = NULL;
    }
    fclose(fp);
    vxCommitArrayRange(file, 0, 0, filename);

    return status;
}
Пример #17
0
// nodeless version of the Phase kernel
vx_status vxPhase(vx_image grad_x, vx_image grad_y, vx_image output)
{
    vx_uint32 x;
    vx_uint32 y;
    vx_df_image format = 0;
    vx_uint8* dst_base = NULL;
    void* src_base_x   = NULL;
    void* src_base_y   = NULL;
    vx_imagepatch_addressing_t src_addr_x;
    vx_imagepatch_addressing_t src_addr_y;
    vx_imagepatch_addressing_t dst_addr;
    vx_rectangle_t rect;
    vx_status status = VX_FAILURE;

    if (grad_x == 0 && grad_y == 0)
        return VX_ERROR_INVALID_PARAMETERS;

    status  = VX_SUCCESS;
    status |= vxQueryImage(grad_x, VX_IMAGE_FORMAT, &format, sizeof(format));
    status |= vxGetValidRegionImage(grad_x, &rect);
    status |= vxAccessImagePatch(grad_x, &rect, 0, &src_addr_x, &src_base_x, VX_READ_ONLY);
    status |= vxAccessImagePatch(grad_y, &rect, 0, &src_addr_y, &src_base_y, VX_READ_ONLY);
    status |= vxAccessImagePatch(output, &rect, 0, &dst_addr, (void **)&dst_base, VX_WRITE_ONLY);

    for (y = 0; y < dst_addr.dim_y; y++)
    {
        for (x = 0; x < dst_addr.dim_x; x++)
        {
            void*     in_x = vxFormatImagePatchAddress2d(src_base_x, x, y, &src_addr_x);
            void*     in_y = vxFormatImagePatchAddress2d(src_base_y, x, y, &src_addr_y);
            vx_uint8* dst  = vxFormatImagePatchAddress2d(dst_base, x, y, &dst_addr);

            /* -M_PI to M_PI */
            double val_x;
            double val_y;

            if (format == VX_DF_IMAGE_F32)
            {
                val_x = (double)(((vx_float32*)in_x)[0]);
                val_y = (double)(((vx_float32*)in_y)[0]);
            }
            else // VX_DF_IMAGE_S16
            {
                val_x = (double)(((vx_int16*)in_x)[0]);
                val_y = (double)(((vx_int16*)in_y)[0]);
            }

            double arct = atan2(val_y,val_x);
            /* 0 - TAU */
            double norm = arct;
            if (arct < 0.0f)
            {
                norm = VX_TAU + arct;
            }

            /* 0.0 - 1.0 */
            norm = norm / VX_TAU;

            /* 0 - 255 */
            *dst = (vx_uint8)((vx_uint32)(norm * 256u + 0.5) & 0xFFu);
            if (val_y != 0 || val_x != 0)
            {
                VX_PRINT(VX_ZONE_INFO, "atan2(%d,%d) = %lf [norm=%lf] dst=%02x\n", val_y, val_x, arct, norm, *dst);
            }
        }
    }

    status |= vxCommitImagePatch(grad_x, NULL, 0, &src_addr_x, src_base_x);
    status |= vxCommitImagePatch(grad_y, NULL, 0, &src_addr_y, src_base_y);
    status |= vxCommitImagePatch(output, &rect, 0, &dst_addr, dst_base);

    return status;
}
Пример #18
0
vx_status vxFWriteImage(vx_image input, vx_array file)
{
    vx_char *filename = NULL;
    vx_size filename_stride = 0;
    vx_uint8 *src[4] = {NULL, NULL, NULL, NULL};
    vx_uint32 p, y, sx, ex, sy, ey, width, height;
    vx_size planes;
    vx_imagepatch_addressing_t addr[4];
    vx_df_image format;
    FILE *fp = NULL;
    vx_char *ext = NULL;
    size_t wrote = 0ul;
    vx_rectangle_t rect;

    vx_status status = vxAccessArrayRange(file, 0, VX_MAX_FILE_NAME, &filename_stride, (void **)&filename, VX_READ_ONLY);
    if (status != VX_SUCCESS || filename_stride != sizeof(vx_char))
    {
        vxCommitArrayRange(file, 0, 0, filename);
        vxAddLogEntry((vx_reference)file, VX_FAILURE, "Incorrect array "VX_FMT_REF"\n", file);
        return VX_FAILURE;
    }
    //VX_PRINT(VX_ZONE_INFO, "filename=%s\n",filename);
    fp = fopen(filename, "wb+");
    if (fp == NULL) {
        vxCommitArrayRange(file, 0, 0, filename);
        vxAddLogEntry((vx_reference)file, VX_FAILURE, "Failed to open file %s\n",filename);
        return VX_FAILURE;
    }

    status |= vxQueryImage(input, VX_IMAGE_WIDTH,  &width,  sizeof(width));
    status |= vxQueryImage(input, VX_IMAGE_HEIGHT, &height, sizeof(height));
    status |= vxQueryImage(input, VX_IMAGE_PLANES, &planes, sizeof(planes));
    status |= vxQueryImage(input, VX_IMAGE_FORMAT, &format, sizeof(format));

    status |= vxGetValidRegionImage(input, &rect);

    sx = rect.start_x;
    sy = rect.start_y;
    ex = rect.end_x;
    ey = rect.end_y;

    ext = strrchr(filename, '.');
    if (ext && (strcmp(ext, ".pgm") == 0 || strcmp(ext, ".PGM") == 0))
    {
        fprintf(fp, "P5\n# %s\n",filename);
        fprintf(fp, "%u %u\n", width, height);
        if (format == VX_DF_IMAGE_U8)
            fprintf(fp, "255\n");
        else if (format == VX_DF_IMAGE_S16)
            fprintf(fp, "65535\n");
        else if (format == VX_DF_IMAGE_U16)
            fprintf(fp, "65535\n");
    }
    for (p = 0u; p < planes; p++)
    {
        status |= vxAccessImagePatch(input, &rect, p, &addr[p], (void **)&src[p], VX_READ_ONLY);
    }
    for (p = 0u; (p < planes) && (status == VX_SUCCESS); p++)
    {
        size_t len = addr[p].stride_x * (addr[p].dim_x * addr[p].scale_x)/VX_SCALE_UNITY;
        for (y = 0u; y < height; y+=addr[p].step_y)
        {
            vx_uint32 i = 0;
            vx_uint8 *ptr = NULL;
            uint8_t value = 0u;

            if (y < sy || y >= ey)
            {
                for (i = 0; i < width; ++i) {
                    wrote += fwrite(&value, sizeof(value), 1, fp);
                }
                continue;
            }

            for (i = 0; i < sx; ++i)
                wrote += fwrite(&value, sizeof(value), 1, fp);

            ptr = vxFormatImagePatchAddress2d(src[p], 0, y - sy, &addr[p]);
            wrote += fwrite(ptr, 1, len, fp);

            for (i = 0; i < width - ex; ++i)
                wrote += fwrite(&value, sizeof(value), 1, fp);
        }
        if (wrote == 0)
        {
            vxAddLogEntry((vx_reference)file, VX_FAILURE, "Failed to write to file!\n");
            status = VX_FAILURE;
            break;
        }
        if (status == VX_FAILURE)
        {
            vxAddLogEntry((vx_reference)file, VX_FAILURE, "Failed to write image to file correctly\n");
            break;
        }
    }
    for (p = 0u; p < planes; p++)
    {
        status |= vxCommitImagePatch(input, NULL, p, &addr[p], src[p]);
    }
    if (status != VX_SUCCESS)
    {
        vxAddLogEntry((vx_reference)file, VX_FAILURE, "Failed to write image to file correctly\n");
    }
    fflush(fp);
    fclose(fp);
    if (vxCommitArrayRange(file, 0, 0, filename) != VX_SUCCESS)
    {
        vxAddLogEntry((vx_reference)file, VX_FAILURE, "Failed to release handle to filename array!\n");
    }

    return status;
}
Пример #19
0
static vx_status vxCheckImageKernel(vx_node node, vx_reference *parameters, vx_uint32 num)
{
    vx_status status = VX_SUCCESS;
    if (num == 3)
    {
        vx_image image = (vx_image)parameters[0];
        vx_scalar fill = (vx_scalar)parameters[1];
        vx_scalar errs = (vx_scalar)parameters[2];
        packed_value_u value;
        vx_uint32 planes = 0u, count = 0u, errors = 0u;
        vx_uint32 x = 0u, y = 0u, p = 0u;
        vx_int32 i = 0;
        vx_imagepatch_addressing_t addr;
        vx_rectangle rect;

        value.dword[0] = 0xDEADBEEF;
        vxAccessScalarValue(fill, &value.dword[0]);
        vxQueryImage(image, VX_IMAGE_ATTRIBUTE_PLANES, &planes, sizeof(planes));
        rect = vxGetValidRegionImage(image);
        for (p = 0u; (p < planes) && (rect); p++)
        {
            void *ptr = NULL;
            status = vxAccessImagePatch(image, rect, p, &addr, &ptr);
            if ((status == VX_SUCCESS) && (ptr))
            {
                for (y = 0; y < addr.dim_y; y+=addr.step_y)
                {
                    for (x = 0; x < addr.dim_x; x+=addr.step_x)
                    {
                        vx_uint8 *pixel = vxFormatImagePatchAddress2d(ptr, x, y, &addr);
                        for (i = 0; i < addr.stride_x; i++)
                        {
                            count++;
                            if (pixel[i] != value.bytes[i])
                            {
                                errors++;
                            }
                        }
                    }
                }
                if (errors > 0)
                {
                    vxAddLogEntry(vxGetContext(node), VX_FAILURE, "Checked %p of %u sub-pixels with 0x%08x with %u errors\n", ptr, count, value.dword, errors);
                }
                vxCommitScalarValue(errs, &errors);
                status = vxCommitImagePatch(image, 0, p, &addr, ptr);
                if (status != VX_SUCCESS)
                {
                    vxAddLogEntry(vxGetContext(node), VX_FAILURE, "Failed to set image patch for "VX_FMT_REF"\n", image);
                }
            }
            else
            {
                vxAddLogEntry(vxGetContext(node), VX_FAILURE, "Failed to get image patch for "VX_FMT_REF"\n", image);
            }
        }
        vxReleaseRectangle(&rect);
        if (errors > 0)
        {
            status = VX_FAILURE;
        }
    }
    return status;
}
Пример #20
0
// nodeless version of the Fast9Corners kernel
vx_status vxFast9Corners(vx_image src, vx_scalar sens, vx_scalar nonm, vx_array points,
                         vx_scalar s_num_corners, vx_border_mode_t *bordermode)
{
    vx_float32 b = 0.0f;
    vx_imagepatch_addressing_t src_addr;
    void *src_base = NULL;
    vx_rectangle_t rect;
    vx_uint8 tolerance = 0;
    vx_bool do_nonmax;
    vx_uint32 num_corners = 0;
    vx_size dst_capacity = 0;
    vx_keypoint_t kp;

    vx_status status = vxGetValidRegionImage(src, &rect);
    status |= vxReadScalarValue(sens, &b);
    status |= vxReadScalarValue(nonm, &do_nonmax);
    /* remove any pre-existing points */
    status |= vxTruncateArray(points, 0);
    status |= vxAccessImagePatch(src, &rect, 0, &src_addr, &src_base, VX_READ_ONLY);
    tolerance = (vx_uint8)b;
    status |= vxQueryArray(points, VX_ARRAY_ATTRIBUTE_CAPACITY, &dst_capacity, sizeof(dst_capacity));

    memset(&kp, 0, sizeof(kp));

    if (status == VX_SUCCESS)
    {
        /*! \todo implement other Fast9 Corners border modes */
        if (bordermode->mode == VX_BORDER_MODE_UNDEFINED)
        {
            vx_int32 y, x;
            for (y = APERTURE; y < (vx_int32)(src_addr.dim_y - APERTURE); y++)
            {
                for (x = APERTURE; x < (vx_int32)(src_addr.dim_x - APERTURE); x++)
                {
                    vx_uint8 strength = vxGetFastCornerStrength(x, y, src_base, &src_addr, tolerance);
                    if (strength > 0)
                    {
                        if (do_nonmax)
                        {
                            if (strength >= vxGetFastCornerStrength(x-1, y-1, src_base, &src_addr, tolerance) &&
                                strength >= vxGetFastCornerStrength(x, y-1, src_base, &src_addr, tolerance) &&
                                strength >= vxGetFastCornerStrength(x+1, y-1, src_base, &src_addr, tolerance) &&
                                strength >= vxGetFastCornerStrength(x-1, y, src_base, &src_addr, tolerance) &&
                                strength >  vxGetFastCornerStrength(x+1, y, src_base, &src_addr, tolerance) &&
                                strength >  vxGetFastCornerStrength(x-1, y+1, src_base, &src_addr, tolerance) &&
                                strength >  vxGetFastCornerStrength(x, y+1, src_base, &src_addr, tolerance) &&
                                strength >  vxGetFastCornerStrength(x+1, y+1, src_base, &src_addr, tolerance))
                                ;
                            else
                                continue;
                        }
                        if (num_corners < dst_capacity)
                        {
                            kp.x = x;
                            kp.y = y;
                            kp.strength = strength;
                            status |= vxAddArrayItems(points, 1, &kp, 0);
                        }
                        num_corners++;
                    }
                }
            }
        }
        else
        {
            status = VX_ERROR_NOT_IMPLEMENTED;
        }
        if (s_num_corners)
            status |= vxWriteScalarValue(s_num_corners, &num_corners);
        status |= vxCommitImagePatch(src, NULL, 0, &src_addr, src_base);
    }

    return status;
}
Пример #21
0
// Compare rectangular region specified within an image and return number of pixels mismatching
size_t CompareImage(vx_image image, vx_rectangle_t * rectRegion, vx_uint8 * refImage, float errLimitMin, float errLimitMax, int frameNumber, const char * fileNameRef)
{
	// get number of planes, image format, and pixel type
	vx_df_image format = VX_DF_IMAGE_VIRT;
	vx_size num_planes = 0; vx_uint32 image_width = 0, image_height = 0;
	ERROR_CHECK(vxQueryImage(image, VX_IMAGE_ATTRIBUTE_WIDTH, &image_width, sizeof(image_width)));
	ERROR_CHECK(vxQueryImage(image, VX_IMAGE_ATTRIBUTE_HEIGHT, &image_height, sizeof(image_height)));
	ERROR_CHECK(vxQueryImage(image, VX_IMAGE_ATTRIBUTE_FORMAT, &format, sizeof(format)));
	ERROR_CHECK(vxQueryImage(image, VX_IMAGE_ATTRIBUTE_PLANES, &num_planes, sizeof(num_planes)));
	// set pixel type and compute frame size in bytes
	vx_enum pixelType = VX_TYPE_UINT8; // default
	if (format == VX_DF_IMAGE_S16) pixelType = VX_TYPE_INT16;
	else if (format == VX_DF_IMAGE_U16) pixelType = VX_TYPE_UINT16;
	else if (format == VX_DF_IMAGE_S32) pixelType = VX_TYPE_INT32;
	else if (format == VX_DF_IMAGE_U32) pixelType = VX_TYPE_UINT32;
	else if (format == VX_DF_IMAGE_F32_AMD || format == VX_DF_IMAGE_F32x3_AMD) pixelType = VX_TYPE_FLOAT32;
	// compare plane by plane
	vx_size errorPixelCountTotal = 0;
	vx_uint8 * pRefPlane = refImage;
	for (vx_uint32 plane = 0; plane < (vx_uint32)num_planes; plane++) {
		vx_imagepatch_addressing_t addr = { 0 };
		vx_uint8 * base_ptr = nullptr;
		ERROR_CHECK(vxAccessImagePatch(image, rectRegion, plane, &addr, (void **)&base_ptr, VX_READ_ONLY));
		vx_uint32 region_width = ((addr.dim_x * addr.scale_x) / VX_SCALE_UNITY);
		vx_uint32 region_height = (addr.dim_y * addr.scale_y) / VX_SCALE_UNITY;
		vx_uint32 plane_width = ((image_width * addr.scale_x) / VX_SCALE_UNITY);
		vx_uint32 plane_height = ((image_height * addr.scale_y) / VX_SCALE_UNITY);
		vx_uint32 plane_width_in_bytes = (format == VX_DF_IMAGE_U1_AMD) ? ((plane_width + 7) >> 3) : (plane_width * addr.stride_x);
		vx_uint32 start_x = ((rectRegion->start_x * addr.scale_x) / VX_SCALE_UNITY);
		vx_uint32 start_y = ((rectRegion->start_y * addr.scale_y) / VX_SCALE_UNITY);
		vx_uint8 * pRef = pRefPlane + start_y * plane_width_in_bytes + start_x * addr.stride_x;
		vx_size errorPixelCount = 0;
		if (pixelType == VX_TYPE_INT16) {
			errorPixelCount = ComparePixels((vx_int16 *)base_ptr, addr.stride_y, (vx_int16 *)pRef, plane_width_in_bytes, region_width, region_height, (vx_int32)errLimitMin, (vx_int32)errLimitMax);
		}
		else if (pixelType == VX_TYPE_UINT16) {
			errorPixelCount = ComparePixels((vx_uint16 *)base_ptr, addr.stride_y, (vx_uint16 *)pRef, plane_width_in_bytes, region_width, region_height, (vx_int32)errLimitMin, (vx_int32)errLimitMax);
		}
		else if (pixelType == VX_TYPE_INT32) {
			errorPixelCount = ComparePixels((vx_int32 *)base_ptr, addr.stride_y, (vx_int32 *)pRef, plane_width_in_bytes, region_width, region_height, (vx_int64)errLimitMin, (vx_int64)errLimitMax);
		}
		else if (pixelType == VX_TYPE_UINT32) {
			errorPixelCount = ComparePixels((vx_uint32 *)base_ptr, addr.stride_y, (vx_uint32 *)pRef, plane_width_in_bytes, region_width, region_height, (vx_int64)errLimitMin, (vx_int64)errLimitMax);
		}
		else if (pixelType == VX_TYPE_FLOAT32) {
			errorPixelCount = ComparePixels((vx_float32 *)base_ptr, addr.stride_y, (vx_float32 *)pRef, plane_width_in_bytes, region_width, region_height, (vx_float32)errLimitMin, (vx_float32)errLimitMax);
		}
		else if (format == VX_DF_IMAGE_U1_AMD) {
			errorPixelCount = ComparePixelsU001((vx_uint8 *)base_ptr, addr.stride_y, (vx_uint8 *)pRef, plane_width_in_bytes, region_width, region_height);
		}
		else {
			errorPixelCount = ComparePixels((vx_uint8 *)base_ptr, addr.stride_y, (vx_uint8 *)pRef, plane_width_in_bytes, region_width, region_height, (vx_int32)errLimitMin, (vx_int32)errLimitMax);
		}
		ERROR_CHECK(vxCommitImagePatch(image, rectRegion, plane, &addr, base_ptr));
		// report results
		errorPixelCountTotal += errorPixelCount;
		if (errorPixelCount > 0) {
			char name[64]; vxGetReferenceName((vx_reference)image, name, sizeof(name));
			printf("ERROR: Image COMPARE MISMATCHED %s plane#%d " VX_FMT_SIZE "-pixel(s) with frame#%d of %s\n", name, plane, errorPixelCount, frameNumber, fileNameRef ? fileNameRef : "???");
		}
		// skip to begnning of next plane
		pRefPlane += plane_height * plane_width_in_bytes;
	}
	return errorPixelCountTotal;
}
Пример #22
0
// nodeless version of the ConvertDepth kernel
vx_status vxConvertDepth(vx_image input, vx_image output, vx_scalar spol, vx_scalar sshf)
{
    vx_uint32 y, x;
    void *dst_base = NULL;
    void *src_base = NULL;
    vx_imagepatch_addressing_t dst_addr, src_addr;
    vx_rectangle_t rect;
    vx_enum format[2];
    vx_enum policy = 0;
    vx_int32 shift = 0;

    vx_status status = VX_SUCCESS;
    status |= vxReadScalarValue(spol, &policy);
    status |= vxReadScalarValue(sshf, &shift);
    status |= vxQueryImage(input, VX_IMAGE_ATTRIBUTE_FORMAT, &format[0], sizeof(format[0]));
    status |= vxQueryImage(output, VX_IMAGE_ATTRIBUTE_FORMAT, &format[1], sizeof(format[1]));
    status |= vxGetValidRegionImage(input, &rect);
    status |= vxAccessImagePatch(input, &rect, 0, &src_addr, &src_base, VX_READ_ONLY);
    status |= vxAccessImagePatch(output, &rect, 0, &dst_addr, &dst_base, VX_WRITE_ONLY);
    for (y = 0; y < src_addr.dim_y; y++)
    {
        for (x = 0; x < src_addr.dim_x; x++)
        {
            if ((format[0] == VX_DF_IMAGE_U8) && (format[1] == VX_DF_IMAGE_U16))
            {
                vx_uint8 *src = vxFormatImagePatchAddress2d(src_base, x, y, &src_addr);
                vx_uint16 *dst = vxFormatImagePatchAddress2d(dst_base, x, y, &dst_addr);
                *dst = ((vx_uint16)(*src)) << shift;
            }
            else if ((format[0] == VX_DF_IMAGE_U8) && (format[1] == VX_DF_IMAGE_S16))
            {
                vx_uint8 *src = vxFormatImagePatchAddress2d(src_base, x, y, &src_addr);
                vx_int16 *dst = vxFormatImagePatchAddress2d(dst_base, x, y, &dst_addr);
                *dst = ((vx_int16)(*src)) << shift;
            }
            else if ((format[0] == VX_DF_IMAGE_U8) && (format[1] == VX_DF_IMAGE_U32))
            {
                vx_uint8 *src = vxFormatImagePatchAddress2d(src_base, x, y, &src_addr);
                vx_uint32 *dst = vxFormatImagePatchAddress2d(dst_base, x, y, &dst_addr);
                *dst = ((vx_uint32)(*src)) << shift;
            }
            else if ((format[0] == VX_DF_IMAGE_U16) && (format[1] == VX_DF_IMAGE_U32))
            {
                vx_uint16 *src = vxFormatImagePatchAddress2d(src_base, x, y, &src_addr);
                vx_uint32 *dst = vxFormatImagePatchAddress2d(dst_base, x, y, &dst_addr);
                *dst = ((vx_uint32)(*src)) << shift;
            }
            else if ((format[0] == VX_DF_IMAGE_S16) && (format[1] == VX_DF_IMAGE_S32))
            {
                vx_int16 *src = vxFormatImagePatchAddress2d(src_base, x, y, &src_addr);
                vx_int32 *dst = vxFormatImagePatchAddress2d(dst_base, x, y, &dst_addr);
                *dst = ((vx_int32)(*src)) << shift;
            }
            else if ((format[0] == VX_DF_IMAGE_U16) && (format[1] == VX_DF_IMAGE_U8))
            {
                vx_uint16 *src = vxFormatImagePatchAddress2d(src_base, x, y, &src_addr);
                vx_uint8 *dst = vxFormatImagePatchAddress2d(dst_base, x, y, &dst_addr);
                if (policy == VX_CONVERT_POLICY_WRAP)
                {
                    *dst = (vx_uint8)((*src) >> shift);
                }
                else if (policy == VX_CONVERT_POLICY_SATURATE)
                {
                    vx_uint16 value = (*src) >> shift;
                    value = (value > UINT8_MAX ? UINT8_MAX : value);
                    *dst = (vx_uint8)value;
                }
Пример #23
0
static vx_status vxEdgeTrace(vx_image norm, vx_threshold threshold, vx_image output)
{
    vx_rectangle_t rect;
    vx_imagepatch_addressing_t norm_addr, output_addr;
    void *norm_base = NULL, *output_base = NULL;
    vx_uint32 y = 0, x = 0;
    vx_int32 lower = 0, upper = 0;
    vx_status status = VX_SUCCESS;
    vxQueryThreshold(threshold, VX_THRESHOLD_ATTRIBUTE_THRESHOLD_LOWER, &lower, sizeof(lower));
    vxQueryThreshold(threshold, VX_THRESHOLD_ATTRIBUTE_THRESHOLD_UPPER, &upper, sizeof(upper));
    vxGetValidRegionImage(norm, &rect);

    status |= vxAccessImagePatch(norm, &rect, 0, &norm_addr, &norm_base, VX_READ_ONLY);
    status |= vxAccessImagePatch(output, &rect, 0, &output_addr, &output_base, VX_WRITE_ONLY);
    if (status == VX_SUCCESS) {
        const vx_uint8 NO = 0, MAYBE = 127, YES = 255;

        /* Initially we add all YES pixels to the stack. Later we only add MAYBE
           pixels to it, and we reset their state to YES afterwards; so we can never
           add the same pixel more than once. That means that the stack size is bounded
           by the image size. */
        vx_uint32 (*tracing_stack)[2] = malloc(output_addr.dim_y * output_addr.dim_x * sizeof *tracing_stack);
        vx_uint32 (*stack_top)[2] = tracing_stack;

        for (y = 0; y < norm_addr.dim_y; y++)
            for (x = 0; x < norm_addr.dim_x; x++)
            {
                vx_uint16 *norm_ptr = vxFormatImagePatchAddress2d(norm_base, x, y, &norm_addr);
                vx_uint8 *output_ptr = vxFormatImagePatchAddress2d(output_base, x, y, &output_addr);

                if (*norm_ptr > upper)
                {
                    *output_ptr = YES;
                    (*stack_top)[0] = x;
                    (*stack_top)[1] = y;
                    ++stack_top;
                }
                else if (*norm_ptr <= lower)
                {
                    *output_ptr = NO;
                }
                else
                {
                    *output_ptr = MAYBE;
                }
            }


        while (stack_top != tracing_stack) {
            int i;
            --stack_top;
            x = (*stack_top)[0];
            y = (*stack_top)[1];

            for (i = 0; i < dimof(dir_offsets); ++i) {
                const struct offset_t offset = dir_offsets[i];
                vx_uint32 new_x, new_y;
                vx_uint8 *output_ptr;

                if (x == 0 && offset.x < 0) continue;
                if (x == output_addr.dim_x - 1 && offset.x > 0) continue;
                if (y == 0 && offset.y < 0) continue;
                if (y == output_addr.dim_y - 1 && offset.y > 0) continue;

                new_x = x + offset.x;
                new_y = y + offset.y;

                output_ptr = vxFormatImagePatchAddress2d(output_base, new_x, new_y, &output_addr);
                if (*output_ptr != MAYBE) continue;

                *output_ptr = YES;

                (*stack_top)[0] = new_x;
                (*stack_top)[1] = new_y;
                ++stack_top;
            }
        }

        free(tracing_stack);

        for (y = 0; y < output_addr.dim_y; y++)
            for (x = 0; x < output_addr.dim_x; x++)
            {
                vx_uint8 *output_ptr = vxFormatImagePatchAddress2d(output_base, x, y, &output_addr);
                if (*output_ptr == MAYBE) *output_ptr = NO;
            }

        status |= vxCommitImagePatch(norm, 0, 0, &norm_addr, norm_base);
        status |= vxCommitImagePatch(output, &rect, 0, &output_addr, output_base);
    }
    return status;
}
Пример #24
0
// nodeless version of NonLinearFilter kernel
vx_status vxNonLinearFilter(vx_scalar function, vx_image src, vx_matrix mask, vx_image dst, vx_border_t *border)
{
    vx_uint32 y, x;
    void *src_base = NULL;
    void *dst_base = NULL;
    vx_imagepatch_addressing_t src_addr, dst_addr;
    vx_rectangle_t rect;
    vx_uint32 low_x = 0, low_y = 0, high_x, high_y;

    vx_uint8 m[C_MAX_NONLINEAR_DIM * C_MAX_NONLINEAR_DIM];
    vx_uint8 v[C_MAX_NONLINEAR_DIM * C_MAX_NONLINEAR_DIM];

    vx_status status = vxGetValidRegionImage(src, &rect);
    status |= vxAccessImagePatch(src, &rect, 0, &src_addr, &src_base, VX_READ_ONLY);
    status |= vxAccessImagePatch(dst, &rect, 0, &dst_addr, &dst_base, VX_WRITE_ONLY);

    vx_enum func = 0;
    status |= vxCopyScalar(function, &func, VX_READ_ONLY, VX_MEMORY_TYPE_HOST);

    vx_size mrows, mcols;
    vx_enum mtype = 0;
    status |= vxQueryMatrix(mask, VX_MATRIX_ROWS, &mrows, sizeof(mrows));
    status |= vxQueryMatrix(mask, VX_MATRIX_COLUMNS, &mcols, sizeof(mcols));
    status |= vxQueryMatrix(mask, VX_MATRIX_TYPE, &mtype, sizeof(mtype));

    vx_coordinates2d_t origin;
    status |= vxQueryMatrix(mask, VX_MATRIX_ORIGIN, &origin, sizeof(origin));

    if ((mtype != VX_TYPE_UINT8) || (sizeof(m) < mrows * mcols))
        status = VX_ERROR_INVALID_PARAMETERS;

    status |= vxCopyMatrix(mask, m, VX_READ_ONLY, VX_MEMORY_TYPE_HOST);

    if (status == VX_SUCCESS)
    {
        vx_size rx0 = origin.x;
        vx_size ry0 = origin.y;
        vx_size rx1 = mcols - origin.x - 1;
        vx_size ry1 = mrows - origin.y - 1;

        high_x = src_addr.dim_x;
        high_y = src_addr.dim_y;

        if (border->mode == VX_BORDER_UNDEFINED)
        {
            low_x += rx0;
            low_y += ry0;
            high_x -= rx1;
            high_y -= ry1;
            vxAlterRectangle(&rect, (vx_int32)rx0, (vx_int32)ry0, -(vx_int32)rx1, -(vx_int32)ry1);
        }

        for (y = low_y; y < high_y; y++)
        {
            for (x = low_x; x < high_x; x++)
            {
                vx_uint8 *dst = vxFormatImagePatchAddress2d(dst_base, x, y, &dst_addr);
                vx_int32 count = readMaskedRectangle_U8(src_base, &src_addr, border, VX_DF_IMAGE_U8, x, y, rx0, ry0, rx1, ry1, m, v);

                qsort(v, count, sizeof(vx_uint8), vx_uint8_compare);

                switch (func)
                {
                case VX_NONLINEAR_FILTER_MIN: *dst = v[0]; break; /* minimal value */
                case VX_NONLINEAR_FILTER_MAX: *dst = v[count - 1]; break; /* maximum value */
                case VX_NONLINEAR_FILTER_MEDIAN: *dst = v[count / 2]; break; /* pick the middle value */
                }
            }
        }
    }

    status |= vxCommitImagePatch(src, NULL, 0, &src_addr, src_base);
    status |= vxCommitImagePatch(dst, &rect, 0, &dst_addr, dst_base);

    return status;
}