OpenCV距离转换不工作,因为它应该
问题描述:
我想使用OpenCV将分辨率2048x2048的图像分割成像素周围分辨率为90x90的一些*像素的较小图像。后来在那些较小的图像上我想使用foveation。我遵循这个例子在foveation一个图像,而是python我正在使用C++。
OpenCV距离转换不工作,因为它应该
Mat mask = Mat::ones(Size(90,90), CV_8UC1) * 255;
circle(mask, CvPoint(45,45), 30, 0, -1);
Mat out; // = Mat::ones(Size(90,90), CV_32FC1) * 0;
distanceTransform(mask, out, CV_DIST_L2, CV_DIST_MASK_PRECISE);
int scale_factor = 10;
Mat filtered = outputImage.clone();
Mat img_float;
filtered.convertTo(img_float,CV_32F,1,0);
for(int k = 0; k < 90; k++){ // y
for(int l = 0; l < 90; l++){ // x
if(out.at<float>(k,l) == 0.0) continue;
float mask_val = ceil(out.at<float>(k,l)/scale_factor);
if(mask_val <= 3) mask_val = 3;
int beginx = l - int(mask_val/2);
if (beginx < 0)
beginx = 0;
int beginy = k - int(mask_val/2);
if (beginy < 0)
beginy = 0;
int endx = l+int(mask_val/2);
if (endx >= 90)
endx = 90-1;
int endy = k+int(mask_val/2);
if (endy >= 90)
endy = 90-1;
int num = 0;
float total = 0;
for (int a = beginx; a < endx; a++){
for(int b = beginy; b < endy; b++){
num ++;
total += img_float.at<float>(a,b);
}
}
filtered.at<float>(k,l) = (total/num);
}
}
namedWindow("Display window", WINDOW_AUTOSIZE);
imshow("Display window", filtered);
waitKey(0);
imwrite(ss.str(), filtered, compression_params);
在另一个问题在这里,我读了,而不是使用3或5中distanceTransform参数我应该使用CV_DIST_MASK_PRECISE。
问题是,我的垫子有时是黑色的,有时是白色的圆形,但它不能被保存或在代码中使用。
下面是结果:
但是,当我使用Python脚本我没有一个问题:
规格:
- 操作系统:Ubuntu的14.04
- CPU:i7-2600 3.50GHz
- RAM:8GB
OpenCV ver。 3.0.0
*我说一些像素,约300万像素。
编辑
下面是其余的代码。问题中的这一部分在保存裁剪后的图像之前就已经过了。
http://pastebin.com/49rLhDcF
Mat outputImage = temp(Rect(lx,ty,abs(rx-lx),abs(by-ty)));
ps:因为有很多像素,在生成大量图像后,我得到分割错误(核心转储)。我知道这与记忆有关,我正在尝试修复它,但我也希望听到您的意见。
答
问题解决了,
我只是补充了这几行。
我用高斯模糊来平滑整个图片,然后我复制了原始像素的值来预制我想要的效果。
for(int j = 0; j < pixels_gray.size(); j++) {
int x = pixels_gray[j].x;
int y = pixels_gray[j].y;
int lx = pixels_gray[j].lx;
int rx = pixels_gray[j].rx;
int ty = pixels_gray[j].ty;
int by = pixels_gray[j].by;
Mat outputImage = image_original(Rect(lx, ty, abs(rx - lx), abs(by-ty)));
Mat mask = Mat::ones(Size(90,90), CV_8UC1) * 255;
CvPoint c = cvPoint(45, 45);
circle(mask, c, 30, 0, -1);
Mat smooth;
for (int i=1; i<11; i=i+2){
GaussianBlur(outputImage, smooth, Size(i, i), 0, 0);
}
for(int my = 0; my < 90; my++){
for(int mx = 0; mx <90; mx++){
Scalar colour = mask.at<uchar>(Point(mx, my));
if(colour.val[0]==255) continue;
smooth.at<Vec3b>(my,mx)[0] = outputImage.at<Vec3b>(my,mx)[0];
smooth.at<Vec3b>(my,mx)[1] = outputImage.at<Vec3b>(my,mx)[1];
smooth.at<Vec3b>(my,mx)[2] = outputImage.at<Vec3b>(my,mx)[2];
}
}
stringstream ss;
ss << dir << "gray_" << y << "_" << x << ".png";
imwrite(ss.str(), smooth, compression_params);
}
'img_float.at(a,b);'
berak
可能你有'outputImage'是一个三通道矩阵。你以某种方式弄乱了1个通道图像和3个通道图像。更多的代码可以帮助.. – Miki
@Miki这里是源代码 http://pastebin.com/49rLhDcF 我只是今天改变它并运行它。我将在周一应用所有这些变化。 到目前为止,问题中的代码在保存修改后的(裁剪后的)图像之前进行。 – Stefan