2

我正在尝试编写一个将平面场应用于图像的 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 都很陌生,所以我不完全确定我错过了什么。该线程似乎表明浮点值可能是原因。我可以转换出浮点数,但我需要保持源代码的 16 位特性。我试过image.convertTo( image, CV_16U );在divide命令之后添加一行,两者CV_16UCV_8U起作用,也不起作用。

非常感谢任何和所有帮助!

编辑

根据下面的建议,我尝试添加一些 imshow 命令来实际测试 opencv 是否正确处理事情。似乎一切正常,直到我执行除法命令。在那之后,我的图像数组最终是空白的。

4

2 回答 2

1

答案可能是您已经得到了正确的图像,因为如果您使用普通图像浏览器打开 16 位图像,通常会完全变暗,因为它们只支持正确显示 8 位图像。

为了解决这个问题,首先尝试使用 OpenCV highgui 显示 16 位图像。你可以做imshow("test",image) ; waitKey(0) ;,看看图像是否正确显示。如果是这样,您可以将图像转换为 8 位Mat img8bit ; image.convertTo(img8bit, CV8U, 255./65535.) ;并 imwrite 这个新的 Mat。

于 2012-12-19T22:10:50.027 回答
1

原来这确实是我的除法命令。我一直将我的代码基于一个同事编写的类似应用程序,所以我去看看他们是如何完成划分的。我不是 100% 确定这是做什么的,但是当我将我的划分更改为这个时它会起作用:

divide( image, flat_img, image, image.depth() == 16 ? UCHAR_MAX : USHRT_MAX );

只是做一个预测,这个条件就是根据图像的深度为我的数据设置标量。divide( image, flat_img, image, image.depth() == 8 ? UCHAR_MAX : USHRT_MAX );我仍然有一个挥之不去的问题是我所拥有的和将来的有什么区别。两者都产生了看似相同的图像。大多数情况下,我试图更好地理解正在发生的事情。

于 2012-12-20T15:09:51.710 回答