OpenCV:16位灰度图像的标准化给出了弱结果

时间:2016-12-16 14:15:19

标签: c++ opencv c++11 image-processing

我想在16位灰度图像中拉伸对比度。但是void normalize(InputArray src, OutputArray dst, double alpha=1, double beta=0, int norm_type=NORM_L2, int dtype=-1, InputArray mask=noArray() )给了我一些更明亮的图像,但仍然太黑了。

文档:     http://docs.opencv.org/2.4/modules/core/doc/operations_on_arrays.html#normalize

表示alpha是下限和beta上限。因此,在16位图像的情况下,我预计0和65535.0是正确的值。我做了一项研究,大多数答案都指出alpha和betha在归一化图像中是最小值和最大值。

#include "stdafx.h"
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
int main()
 {
    cv::Mat image;
    image = cv::imread("darkImage.tif", CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_GRAYSCALE);

if (!image.data)                           
    {
        std::cout << "Could not open or find the image" << std::endl;
        return -1;
    }

    cv::namedWindow("Original", CV_WINDOW_NORMAL | CV_WINDOW_KEEPRATIO);
    cv::imshow("Original", image);

    cv::normalize(image, image, 0, 65535.0, cv::NORM_MINMAX, CV_16U);
    cv::namedWindow("Normalize", CV_WINDOW_NORMAL | CV_WINDOW_KEEPRATIO);
    cv::imshow("Normalize", image);
    cv::waitKey();

    return 0;

}

Original and Normalized image表明对比度增强还不够。 ImageJ规范化给了我更好的result

alpha和beta值是否适合16位图像? 我是opencv的新手,任何帮助都是相关的。

我使用:opencv3.1,VisualStudio2015,W10,64bit

1 个答案:

答案 0 :(得分:0)

是的,可能直方图均衡是要走的路。 EqualizeHist不适用于16位。所以我建议

image.convertTo(image,CV_8U,1./256.);

image.convertTo(image,CV_32F);

接着是

equalizeHist(image,imageEq);

尝试使用8位选项并且为true,但在截断期间可能会丢失信息。我没有试过浮动,但我怀疑它最终会在内部截断/分箱,这就失去了漂浮的目的。

或者,如果你想正确地做并且不关心运行时/开发时间,你可以实现一个16位直方图,然后是一个16位到8位的查找表,遵循这个想法直方图均衡/ CLAHE背后。 (制作累积分布函数并将此65K向量作为查找表直接应用于图像,以使结果均匀分布。)

或者如果你想做你自己的cv :: normalize()版本来给出居中的平均值和合理的标准差,你可以这样做:

Scalar imMean, imStd;
meanStdDev(image, imMean, imStd);
double a = (1<<16)*(0.25/imStd.val[0]);   // give equalized image a stdDev of 0.25
double b = (1<<16)*0.5 - a*imMean.val[0]; // give equalized image a mean of 0.5
imageEq = a*image+b;