大津的方法问题?

信息处理 图像处理 图像分割
2022-02-22 22:00:29

我对 Otsu 的方法有疑问。我想实现直方图来计算有多少个“和”。对于 Otsu 的方法,我有一个书中的代码,它运行没有问题。这是图片

这里.

我已经实现了一个代码来计算直方图。这是我的代码的输出。

------------------
    0 : 14332
    1 : 2102
    2 : 1387
    3 : 745
    4 : 221
    5 : 117
    6 : 27
    7 : 9
  248 : 6
  249 : 12
  250 : 48
  251 : 162
  252 : 396
  253 : 830
  254 : 1377
  255 : 28554
------------------

这是我的代码:

I = imread('images.jpg');
level = graythresh(I);
BW = im2bw(I, level);
imshow(BW)
imwrite(BW, 'img.jpg');

这是我的 C++ 代码。

#include <opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv\cv.h>
#include <map>
#include <iomanip>

std::map<int, int> computeHistogram(const cv::Mat& image)
{
    std::map<int, int> histogram;

    for ( int row = 0; row < image.rows; ++row)
    {
        for ( int col = 0; col < image.cols; ++col)
        {
          ++histogram[(int)image.at<uchar>(row, col)];

        }
    }

    return histogram;
}

void printHistogram(const std::map<int, int>& histogram)
{
    std::map<int, int>::const_iterator histogram_iter;
    std::cout << "\n------------------\n";
    for( histogram_iter = histogram.begin(); histogram_iter != histogram.end(); ++histogram_iter)
    {
      std::cout << std::setw(5) << histogram_iter->first <<  " : " << histogram_iter->second << "\n";
    }
    std::cout << "------------------\n";
}

int main(int argc, char **argv)
{
    cv::Mat img = cv::imread("img.jpg", CV_BGR2GRAY);
    printHistogram(computeHistogram(img));
    return 0;
}

为什么会是这样的结果?我期待的是多少 255 和 0(仅限黑色和白色)。此外,如果我运行另一张图片,我会得到另一个范围为 0-255 的结果。

2个回答

jpg 是一种压缩存储格式,无论您的图像是多么二进制,您几乎总是会在结果图像中得到灰度值(由于压缩)。请将其另存为 png 并重试。

(另请注意,您仍然有 0 和 255 作为主要 bin,因为 jpg 通常会在边缘附近退化,这构成图像中的一小部分。)

显然不仅仅是 0 和 255 值像素。我建议实施阈值预处理器。通过这种方式,您可以将任何接近白色的东西转换为全白,并将任何接近黑色的东西转换为全黑。不确定您使用的是什么语言,但这是我的意思的一个例子。

for (i = 0; i < columnsSize, i++){
    for (j = 0; j < rowsSize, j++){
       if (image(i, j) < 100)   image(i,j) = 0;
       else  image(i,j) = 255;
    }
}

更好的是,阈值 + 计数器

int black = 0;
int white = 0;
    for (i = 0; i < columnsSize, i++){
        for (j = 0; j < rowsSize, j++){
           if (image(i, j) < 100)   {image(i,j) = 0; black++}
           else  {image(i,j) = 255; white++}
        }
    }