opencv — размытие изображения по стандартному среднему переполнению стека

Я пытаюсь размыть изображение, не используя предопределенные функции opencv, такие как blur (). Я использую стандартное среднее, а не взвешенное среднее. Вот мой код, но результат все тот же с входным изображением. это для 3х3.

    IplImage* img = cvLoadImage(argv[1]);
IplImage* dst = cvCloneImage(img);

height = img->height;
width = img->width;
step = img->widthStep;
channels = img->nChannels;
data = (uchar *)img->imageData;

height2    = dst->height; // row
width2     = dst->width; // col
step2      = dst->widthStep; // size of aligned image row in bytes
channels2  = dst->nChannels;
dstData      = (uchar *)dst->imageData;
int total = 0;

//blur
for (i = 0; i < height; i++) {
for (j = 0; j < width; j++) {
for (x = 0; x <= 2; x++)
for (y = 0; y <= 2; y++)
total =(data[x-1,y-1]+data[x-1,y]+data[x-1,y+1]+
data[x,y-1]+data[x,y]+data[x,y+1]+
data[x+1,y-1]+data[x+1,y]+data[x+1,y+1])/9;
dstData[i,j] = total;
}
}

я думаю, что моя проблема в этом

                       total =(data[x-1,y-1]+data[x-1,y]+data[x-1,y+1]+
data[x,y-1]+data[x,y]+data[x,y+1]+
data[x+1,y-1]+data[x+1,y]+data[x+1,y+1])/9;
dstData[i,j] = total;

что можно сделать?

0

Решение

полная программа, которая показывает, как это сделать. у вас несколько ошибок, 1) неверный доступ к пикселям (http://www.comp.leeds.ac.uk/vision/opencv/iplimage.html). 2) неправильная петля размытия, вы всегда получаете данные из верхнего левого угла 3х3. если доступ к пикселям правильный, вы должны получить постоянное изображение в формате dst.

Другое дело, что вам также необходимо позаботиться о канальной информации, обойти эту программу, прочитав одноканальное изображение. в противном случае вам нужно будет сделать размытие для каждого канала

#include <opencv2/opencv.hpp>int main(int argc, char* argv[])
{

IplImage* img = cvLoadImage("c:/data/2.jpg",0);
IplImage* dst = cvCloneImage(img);
int height,width,step,channels;
int height2,width2,step2,channels2;

height = img->height;
width = img->width;
step = img->widthStep;
channels = img->nChannels;
uchar* data = (uchar *)img->imageData;

height2    = dst->height; // row
width2     = dst->width; // col
step2      = dst->widthStep; // size of aligned image row in bytes
channels2  = dst->nChannels;
uchar* dstData      = (uchar *)dst->imageData;
int total = 0;
int i,j,x,y,tx,ty;
//blur
for (i = 0; i < height; i++) {
for (j = 0; j < width; j++) {
int ksize=3;
total=0;
for (x = -ksize/2; x <=ksize/2; x++)
for (y = -ksize/2; y <=ksize/2; y++)
{
tx=i+x;
ty=j+y;
if(tx>=0&&tx<height && ty>=0 && ty<width)
{
total+=data[tx*step+ty];
}
}

dstData[i*step+j] = total/ksize/ksize;
}
}
cvShowImage("img",img);
cvShowImage("dst",dst);
cvWaitKey(0);
}
1

Другие решения

Предположим, что присваивание 0 пикселям вне диапазона, следующий код должен быть тем, что вы хотите. Ядро my_averageФункция вычисляет среднее значение окна 3 * 3 с центром в i а также j,

for (i = 0; i < height; i++)
for (j=0; j < width; j++)
dstData[i*width+j] = my_average(data, i, j, height, width);

double my_average(uchar * data, int y, int x, int height, int width) {
double sum = 0;
if(x-1 >= 0 && y-1 >= 0) {
sum += data[(y-1)*width + x-1];
}
if(x-1 >= 0) {
sum += data[y*width + x-1];
}
if(x-1 >= 0 && y+1 < height) {
sum += data[(y+1)*width + x-1];
}
if(y-1 >= 0) {
sum += data[(y-1)*width + x];
}
sum += data[y*width + x];
if(y+1 < height) {
sum += data[(y+1)*width + x];
}
if(x+1 < width && y-1 >= 0) {
sum += data[(y-1)*width + x+1];
}
if(x+1 < width) {
sum += data[y*width + x+1];
}
if(x+1 < width && y+1 < height) {
sum += data[(y+1)*width + x+1];
}

return sum/9;
}
0

По вопросам рекламы [email protected]