【问题标题】:OpenCV: Normalization of 16bit grayscale image gives weak resultOpenCV:16位灰度图像的归一化结果较弱
【发布时间】:2023-03-13 07:10:02
【问题描述】:

我想在 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

【问题讨论】:

  • 您是否尝试过使用任何均衡技术?... 直方图均衡?为什么你只坚持简单的对比度增强?

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


【解决方案1】:

是的,可能直方图均衡是要走的路。 EqualizeHist 不适用于 16 位。所以我会推荐一个

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

image.convertTo(image,CV_32F);

紧随其后

equalizeHist(image,imageEq);

8 位选项已尝试过且为真,但在截断期间可能会丢失信息。我还没有尝试过浮动,但我怀疑它最终会在内部截断/合并,这违背了浮动的目的。

或者,如果您想正确地执行此操作并且不关心运行时/开发时,您可以实现一个 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;

【讨论】:

  • 关键是,我必须在输入和输出上坚持 16 位。而且方法也应该比较快。我有科学相机,它可以提供高达 30 fps 的 2.5Kx2.1K 像素图像。我仍然想知道为什么 cv::normalization() 不能正确增强我的形象。是我的图片不适合这种方法还是参数错误?
  • 啊,好的。在这种情况下,您可以按照已编辑的方式在 5 行中自己进行规范化。
猜你喜欢
  • 2012-06-13
  • 1970-01-01
  • 2021-11-25
  • 1970-01-01
  • 1970-01-01
  • 2015-06-29
  • 2020-05-15
  • 1970-01-01
  • 2017-07-31
相关资源
最近更新 更多