How to access pixels by using pointer in OpenCV C++?
define pc(image, x, y, c) image->imageData[(image->widthStep * y) + (image->nChannels * x) + c]
I think this is the accessing the image pixel using C pointer. Am I right? But I don't know what this code means and I don't know how to write this code in OpenCV C++.
It was used in the following code.
void Msrcr::FilterGaussian(IplImage* img, double sigma)
{
int i, j, k, source, filter_size;
vector<int> kernel;
IplImage* temp;
int v1, v2, v3;
// Reject unreasonable demands
// 设置上限
if ( sigma > 300 ) sigma = 300;
// get needed filter size (enforce oddness)
// 获取需要的滤波尺寸,且强制为奇数;
filter_size = (int)floor(sigma*6) / 2;
filter_size = filter_size * 2 + 1;
// Create Kernel
// 创建内核
kernel = CreateFastKernel(sigma);
temp = cvCreateImage(cvSize(img->width, img->height), img->depth, img->nChannels);
// filter x axis
// X轴滤波
for (j = 0; j < temp->height; j++)
{
for (i = 0; i < temp->width; i++)
{
// inner loop has been unrolled
// 内层循环已经展开
v1 = v2 = v3 = 0;
for (k = 0; k < filter_size; k++)
{
source = i + filter_size / 2 - k;
if (source < 0) source *= -1;
if (source > img->width - 1) source = 2*(img->width - 1) - source;
v1 += kernel[k] * (unsigned char)pc(img, source, j, 0);
if (img->nChannels == 1) continue;
v2 += kernel[k] * (unsigned char)pc(img, source, j, 1);
v3 += kernel[k] * (unsigned char)pc(img, source, j, 2);
}
// set value and move on
pc(temp, i, j, 0) = (char)int2smallint(v1);
if (img->nChannels == 1) continue;
pc(temp, i, j, 1) = (char)int2smallint(v2);
pc(temp, i, j, 2) = (char)int2smallint(v3);
}
}
// filter y axis
// Y轴滤波
for (j = 0; j < img->height; j++)
{
for (i = 0; i < img->width; i++)
{
v1 = v2 = v3 = 0;
for (k = 0; k < filter_size; k++)
{
source = j + filter_size / 2 - k;
if (source < 0) source *= -1;
if (source > temp->height - 1) source = 2*(temp->height - 1) - source;
v1 += kernel[k] * (unsigned char)pc(temp, i, source, 0);
if (img->nChannels == 1) continue;
v2 += kernel[k] * (unsigned char)pc(temp, i, source, 1);
v3 += kernel[k] * (unsigned char)pc(temp, i, source, 2);
}
// set value and move on
pc(img, i, j, 0) = (char)int2smallint(v1);
if (img->nChannels == 1) continue;
pc(img, i, j, 1) = (char)int2smallint(v2);
pc(img, i, j, 2) = (char)int2smallint(v3);
}
}
cvReleaseImage( &temp );
}
This is the full program link of this program.
can you post an example of how it's been used? I have an educated guess of what it is doing based off of this declaration but I'd be more certain if I see its use.
I have added an example of how this code is used. Sorry for late, I had away from my computer for days.
apart from the dead c-api code, i'm pretty sure, you should NOT write any code like that.
opencv has several ways of applying gaussian filters / kernels, reinventing the wheel with per-pixel code is outright silly.
Sorry, sir. I don't get it. I have to rewrite the Gaussian convolution in CUDA code for my project. I couldn't use the cv::cuda.
do you realize,that CUDA isa totally different story?
I want to use OpenCV to load the image need to process in CUDA. Is that I don't need to use the pointer? Is there any efficient way to access?
What @berak is trying to tell you is that you should avoid reimplementing operations from scratch especially if, 1: they already exist in the library and 2: require manual per pixel image/matrix access. The method you posted simply applies a Gaussian filter to the image using
sigma
as its kernel. OpenCV already has this method and its called Gaussian blur and here is an example of how to use it. Regarding your CUDA comment, if you TRULY want to leverage it then you should start here and figure out what methods you'd need.have a look at this https://blog.csdn.net/daoqinglin/arti...
@eshirima Thank you!