Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Opencv 将Mat传递给OpenCL内核会导致分段错误_Opencv_Image Processing_Segmentation Fault_Opencl_Mat - Fatal编程技术网

Opencv 将Mat传递给OpenCL内核会导致分段错误

Opencv 将Mat传递给OpenCL内核会导致分段错误,opencv,image-processing,segmentation-fault,opencl,mat,Opencv,Image Processing,Segmentation Fault,Opencl,Mat,我想为FGPA(不支持OpenCV OpenCL)将OpenCL Mat传递给自编的OpenCL内核 主机-代码: Mat img = imread( "template.jpg", IMREAD_GRAYSCALE ); Mat output(img.rows, img.cols, CV_8UC1); // Program, Context already declared // Create Kernel cl_kernel kernel = NULL; kernel = clCreateK

我想为FGPA(不支持OpenCV OpenCL)将OpenCL Mat传递给自编的OpenCL内核

主机-代码:

Mat img = imread( "template.jpg", IMREAD_GRAYSCALE );
Mat output(img.rows, img.cols, CV_8UC1);
// Program, Context already declared
// Create Kernel
cl_kernel kernel = NULL;
kernel = clCreateKernel(program, "copy", &status);
// Create Command Queue and associate it with the device you want to execute on
cl_command_queue cmdQueue;
cmdQueue = clCreateCommandQueue(context,devices[0], 0,  &status);

// Buffer, prob i do something wrong here
cl_mem buffer_img = clCreateBuffer(context,CL_MEM_READ_ONLY, sizeof(uint) * img.cols * img.rows,    NULL,&status);
cl_mem buffer_outputimg = clCreateBuffer(context,CL_MEM_WRITE_ONLY, sizeof(uint) * img.cols * img.rows,NULL,&status);

status = clEnqueueWriteBuffer(cmdQueue, buffer_img,CL_FALSE,0,sizeof(uint) * img.cols * img.rows,&img,0,NULL,NULL);
// set kernel arguments
status = clSetKernelArg(kernel,0,sizeof(cl_mem),&buffer_img);
status = clSetKernelArg(kernel,1,sizeof(cl_mem),&buffer_outputimg);

size_t globalWorkSize[2];
globalWorkSize[0] = img.cols;
globalWorkSize[1] = img.rows;
status = clEnqueueNDRangeKernel(cmdQueue,kernel,2,NULL, globalWorkSize, NULL,0, NULL,NULL);
clEnqueueReadBuffer(cmdQueue,buffer_outputimg,CL_TRUE,0,sizeof(uint) * img.cols * img.rows, &output,    0,  NULL,   NULL);

//stop cpu till queue is finish
clFinish(cmdQueue);
内核代码:

__kernel void copy(__global  uchar *  input, __global  uchar *  output) 
{
    const int x = get_global_id(0);
    const int y = get_global_id(1);
    //copy
    output[y * get_global_size(0) + x] = input[y * get_global_size(0) + x] ;
}
当在FPGA上执行时,我得到一个分段错误,这很可能是由于OpenCV Mat的错误处理

编辑: 按照api55的建议编辑主机代码,解决了以下问题:

Mat img = imread( "scene.jpg", IMREAD_GRAYSCALE );
Mat output(img.rows, img.cols, CV_8UC1);
// Program, Context already declared
// Create Kernel
cl_kernel kernel = NULL;
kernel = clCreateKernel(program, "copy", &status);
// Create Command Queue and associate it with the device you want to execute on
cl_command_queue cmdQueue;
cmdQueue = clCreateCommandQueue(context,devices[0], 0,  &status);
checkError(status, "Failed to create commadnqueue");

// Buffer
cl_mem buffer_img = clCreateBuffer(context,CL_MEM_READ_ONLY, sizeof(uchar) * img.cols * img.rows,   NULL,&status);
cl_mem buffer_outputimg = clCreateBuffer(context,CL_MEM_WRITE_ONLY, sizeof(uchar) * img.cols * img.rows,NULL,&status);
checkError(status, "Failed to create buffer_mask");

status = clEnqueueWriteBuffer(cmdQueue, buffer_img,CL_FALSE,0,sizeof(uchar) * img.cols * img.rows,img.data,0,NULL,NULL);
checkError(status, "Failed to enqueue buffer_img");


status = clSetKernelArg(kernel,0,sizeof(cl_mem),&buffer_img);
status = clSetKernelArg(kernel,1,sizeof(cl_mem),&buffer_outputimg);

size_t globalWorkSize[2];
globalWorkSize[0] = img.cols;
globalWorkSize[1] = img.rows;
status = clEnqueueNDRangeKernel(cmdQueue,kernel,2,NULL, globalWorkSize, NULL,0, NULL,NULL);
clEnqueueReadBuffer(cmdQueue,buffer_outputimg,CL_TRUE,0,sizeof(uchar) * img.cols * img.rows, output.data,0,NULL,NULL);

imwrite("output.jpg", output);

我对opencl没有太多经验,但我认为这是一个opencv/c++问题

opencv mat数据位于
img.data
中,这是一个
uchar*
大小为
sizeof(T)*channels*rows*cols
的数据

通常,加载图像时,
T
为uchar,通道数为3(除非是灰度img)。3通道uchar为每像素24位,灰度(加载时)为每像素8位,您使用的是32位大小的
uint
。在某一点上,它会超出内存并产生分段错误。此外,如果不在结构中使用数据指针,则可能复制的是头信息和指向数据的指针,而不是数据本身

我建议您在以下位置更改
&img

status = clEnqueueWriteBuffer(cmdQueue, buffer_img,CL_FALSE,0,sizeof(uint) * img.cols * img.rows,&img,0,NULL,NULL);
img.data

最后,您需要有正确的数据。我不确定opencl是否可以使用uchar,但如果不能,请将
cv::Mat
更改为其他类型,如下所示:

img.convertTo(img, CV_32S);
加载图像后。这会将其更改为
int
。。。opencv不支持具有无符号整数的矩阵。。。只需确保在其他位置(即
sizeof(uint)
)相应地更改它,如果您转换输入,请记住使用相同的类型创建输出


如果您喜欢浮动,请使用
CV_32F
,如果您喜欢双
CV_64F

非常感谢!!您保存了我的一天:D将&img更改为img.data并将uint更改为uchar解决了问题