2014-11-14 173 views
1

我有我彼此非常简单地减去两个图像:现在防止信息丢失

Mat foo, a, b; 
...//imread onto a and b or somesuch 
foo = a - b; 

,据我了解,进入进底片(或超过255的任何像素值这件事)将被设置为零。如果是这样,我想知道是否有任何方法允许它在零以下,以便我可以稍后调整图像而不会丢失信息。

如果简化了事情,我正在处理灰度图像。

+2

你可以使用'CV :: absDiff'功能,也可以转换为符号的数据类型(如'CV_16S'),并得到负值了。 – Micka 2014-11-14 16:22:33

+0

听起来不错。我如何从8UC1更改为16SC1(例如)并返回?或者我可以使用imwrite()而不将垫子转换回CV_8UC1?如果是这样,当我使用imwrite时负值会发生什么?尽管我可能会先调整图像。 – 2014-11-18 13:53:32

+0

尝试'yourMat.convertTo(...)'转换为其他类型。当转换为更有限的类型时,可以使用alpha和beta参数来适应类型限制,否则将使用饱和度投射。 http://docs.opencv.org/modules/core/doc/basic_structures.html#mat-convertto您可以使用'imshow',并且afaik 0值对于签名类型将显示为灰色。不知道你是否可以直接使用'imwrite',文档说你只能使用'8U'和'16U'类型,如果它工作的话,可能会有一些不直观的转换/缩放/翻译你的颜色。我很快就会写出答案。 – Micka 2014-11-18 14:00:18

回答

1

这是怎样一个简单的转换=>。减去=> convertAndScaleBack应用将如下所示:

输入:

enter image description here

enter image description here

INT main()的 { cv :: Mat input = cv :: imread(“.. /inputData/Lenna.png“,CV_LOAD_IMAGE_GRAYSCALE); cv :: Mat input2 = cv :: imread(“../ inputData/Lenna_edges.png”,CV_LOAD_IMAGE_GRAYSCALE);

cv::Mat input1_16S; 
    cv::Mat input2_16S; 

    input.convertTo(input1_16S, CV_16SC1); 
    input2.convertTo(input2_16S, CV_16SC1); 

    // compute difference of 16 bit signed images 
    cv::Mat diffImage = input1_16S-input2_16S; 

    // now you have a 16S image that has some negative values 

    // find minimum and maximum values: 
    double min, max; 
    cv::minMaxLoc(diffImage, &min, &max); 
    std::cout << "min pixel value: " << min<< std::endl; 

    cv::Mat backConverted; 

    // scale the pixel values so that the smalles value is 0 and the largest one is 255 
    diffImage.convertTo(backConverted,CV_8UC1, 255.0/(max-min), -min); 

    cv::imshow("backConverted", backConverted);   
    cv::waitKey(0); 
} 

输出:

enter image description here

+0

作为参考,在转换时默认使用的[saturate_cast](http://docs.opencv.org/modules/core/doc/utility_and_system_functions_and_macros.html#saturate-cast)的链接。 – 2014-11-18 15:55:54