Reputation: 657
I am trying to make blur convolution with custom float
array.
My array is defined as float array[width*height]
. I edited these functions, so it can work with custom array, and not only OpenCV cv::Mat
My code looks like this:
int reflect(int M, int x)
{
if(x < 0)
{
return -x - 1;
}
if(x >= M)
{
return 2*M - x - 1;
}
return x;
}
void separable2DConvolution(float * data, Size dataSize, float *kernel, int kernelSize)
{
// make copy of original image
float * dataCopy = new float[dataSize.width()*dataSize.height()];
memcpy(dataCopy, data, dataSize.width()*dataSize.height());
float * temp = new float[dataSize.width()*dataSize.height()];
memcpy(temp, data, dataSize.width()*dataSize.height());
float sum;
int x1, y1;
int kernelRadius = floor(kernelSize/2);
// along y - direction
for(int y = 0; y < dataSize.height(); y++){
for(int x = 0; x < dataSize.width(); x++){
sum = 0.0;
for(int i = -kernelRadius; i <= kernelRadius; i++){
y1 = reflect(dataSize.height(), y - i);
sum = sum + kernel[i + kernelRadius]*dataCopy[y1*x+y1];
}
temp[y*x+y] = sum;
}
}
// along x - direction
for(int y = 0; y < dataSize.height(); y++){
for(int x = 0; x < dataSize.width(); x++){
sum = 0.0;
for(int i = -kernelRadius; i <= kernelRadius; i++){
x1 = reflect(dataSize.width(), x - i);
sum = sum + kernel[i + kernelRadius]*temp[x1*y+x1];
}
data[x*y+y] = sum;
}
}
delete [] temp;
delete [] dataCopy;
}
Array is passed to separable2DConvolution
as data
, Size
is custom class with defined width and height (both are valid and greater than 0), kernel
is normalized Gaussian array (almost same as the one from cv::getGaussianKernel
) and kernelSize
is size of Gaussian array (I'm using size 11).
I use this function to replace cv::sepFilter2D
from OpenCV, but somehow, output is different. After using my function, I am converting image to see difference.
OpenCV output has (as expected) "blurred" values, but with the very same input passed to my function, the first third is noised (not blurred at all) and the other part of image is intact.
What's problem with my code?
Thank you for your help!
Upvotes: 1
Views: 648
Reputation: 32732
Your subscripting for saving the pixel sums is wrong. temp[y*x+y]
will write all the results for the first column to the first pixel (temp[0]
). Many other pixels will be unchanged. You probably want temp[y * dataSize.width() + x]
, with a similar change for data[x*y+y]
in the next loop and when calculating subscripts to read the pixel values.
Unrelated, you don't need to memcpy
the bitmap to make copies since you should be writing to every pixel in the image. You don't need dataCopy
at all, since the original data
array hasn't been changed yet.
Using floor
is overkill for an integer. Since kernelSize
is positive, you can just say int kernelRadius = kernelSize / 2;
since this will round down.
Upvotes: 2