我正在尝试编写一个将平面应用于图像的C ++程序。它应该加载图像并将其除以另一个加载的图像,然后将其导出为PNG。我的程序编译正确,但只生成全黑图像。
#include <climits>
#include <stdio.h>
#include <string>
#include <opencv/cv.h>
#include <opencv/highgui.h>
using namespace cv;
using namespace std;
int main( int argc, char *argv[] )
{
const char *flat_file = argv[1];
const char *img_file = argv[2];
const char *out_file = argv[3];
Mat flat_img;
flat_img = imread( flat_file, CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH );
Mat image;
image = imread( img_file, CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH );
GaussianBlur( flat_img, flat_img, cv::Size(3,3), 0, 0, BORDER_REPLICATE );
divide( image, flat_img, image, 1.0, -1 );
imwrite( out_file, image );
return 0;
}
所有输入文件都是16位TIFF。目前,生成的输出文件是16位PNG,具有正确的像素尺寸,但完全是黑色。
我对C ++和OpenCV都很陌生,所以我不完全确定我缺少什么。 This thread似乎表明浮点值可能是原因。我很好地转换出浮点,但我需要保持源的16位特性。我尝试在除法命令之后添加一行image.convertTo( image, CV_16U );
,CV_16U
和CV_8U
都没有效果。
非常感谢任何和所有帮助!
修改
根据下面的建议,我尝试添加一些imshow命令来实际测试opencv是否正确处理了事情。似乎一切正常,直到我的分区命令。之后,我的图像数组最终变成空白。
答案 0 :(得分:1)
答案可能是你已经得到了正确的图像,因为如果你使用普通的图像浏览器打开16位图像,它通常会完全变暗,因为它们只支持正确显示8位图像。
要解决此问题,首先尝试使用OpenCV highgui显示16位图像。
您可以imshow("test",image) ; waitKey(0) ;
查看图像是否正确显示。如果是这样,你可以通过Mat img8bit ; image.convertTo(img8bit, CV8U, 255./65535.) ;
将图像转换为8位,然后将这个新的Mat格式化。
答案 1 :(得分:1)
事实证明这确实是我的分裂命令。我一直把我的代码基于一个同事写的类似应用程序,所以我去了看他们是如何完成这个部门的。我不是百分之百地确定这是在完成什么,但是当我改变我的分歧时它会起作用:
divide( image, flat_img, image, image.depth() == 16 ? UCHAR_MAX : USHRT_MAX );
只是进行预测,条件是根据图像的深度为我的数据设置标量。我仍然有一个挥之不去的问题是我和divide( image, flat_img, image, image.depth() == 8 ? UCHAR_MAX : USHRT_MAX );
之间的区别。两者都产生看似相同的图像。大多数情况下,我正在努力了解发生了什么事情。