我试图在不使用opencv预定义函数(如blur())的情况下模糊图像。我使用的是标准平均值而不是加权平均值。这是我的代码,但输入图像的结果仍然相同。这是3x3。
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)
一个完整的程序,展示了如何做到这一点。你有几个错误,1)不正确的像素访问(http://www.comp.leeds.ac.uk/vision/opencv/iplimage.html)。 2)模糊循环错误,你总是从左上角3x3角获取数据。如果像素访问是正确的,你应该在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)
假设将0分配给超出范围的像素,以下代码应该是您想要的。核心是my_average
函数,它计算以i
和j
为中心的3 * 3窗口的平均值。
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;
}