c++ 是否有办法使用OpenCV均衡每样本16位图像的直方图?

6l7fqoea  于 2023-03-05  发布在  其他
关注(0)|答案(3)|浏览(205)

我使用的是16位/样本图像。
有没有一种(简单的)方法可以对这样的图像进行直方图均衡化(转换为8bps不是一个选项)?

23c0lvtd

23c0lvtd1#

OpenCV中的equalizeHist仅采用8位数据。
但OpenCV中的图像规格化并不限于8位数据。请参阅此处的说明。在您的情况下,函数调用应如下所示:

normalize(src_image, dst_image, 0, 65535, NORM_MINMAX);

如果你想提高图像的对比度,首先尝试标准化,只有当它不起作用时才尝试均衡化。2标准化更快,破坏性更小。
参考:http://answers.opencv.org/question/3176/improve-contrast-of-a-16u-image/

x6yk4ghg

x6yk4ghg2#

到目前为止,OpenCV equalizeHist只支持8位图像,我已经在OpenCV实现here的基础上创建了16位直方图均衡函数here

void equalizeHist16Bit(const cv::Mat &_src, cv::Mat &_dst)
{
    _dst = _src.clone();

    const int hist_sz = 65536;
    int *hist = new int[hist_sz] {};
    int *lut = new int[hist_sz] {};

    for (int y = 0; y < _src.rows; y++)
        for (int x = 0; x < _src.cols; x++)
            hist[(int)_src.at<unsigned short int>(y, x)]++;

    auto i = 0;
    while (!hist[i]) ++i;

    auto total = (int)_src.total();
    if (hist[i] == total) 
    {
        _dst.setTo(i);
        return;
    }

    float scale = (hist_sz - 1.f) / (total - hist[i]);
    auto sum = 0;

    for (lut[i++] = 0; i < hist_sz; ++i) 
    {
        sum += hist[i];
        lut[i] = cv::saturate_cast<ushort>(sum * scale);
    }

    for (int y = 0; y < _src.rows; y++)
        for (int x = 0; x < _src.cols; x++)
        {
            _dst.at<unsigned short int>(y, x) = lut[(int)_src.at<unsigned short int>(y, x)];
        }
}
t98cgbkg

t98cgbkg3#

python中的简单实现参考:https://github.com/torywalker/histogram-equalizer/blob/master/HistogramEqualization.ipynb

import cv2
import numpy as np
import matplotlib.pyplot as plt
img_tif=cv2.imread("scan.tif",cv2.IMREAD_ANYDEPTH)
img = np.asarray(img_tif)
flat = img.flatten()
hist = get_histogram(flat,65536)
#plt.plot(hist)

cs = cumsum(hist)
# re-normalize cumsum values to be between 0-255

# numerator & denomenator
nj = (cs - cs.min()) * 65535
N = cs.max() - cs.min()

# re-normalize the cdf
cs = nj / N
cs = cs.astype('uint16')
img_new = cs[flat]
#plt.hist(img_new, bins=65536)
#plt.show(block=True)
img_new = np.reshape(img_new, img.shape)
cv2.imwrite("contrast.tif",img_new)

相关问题