opencv实验三(C++)——图像二值化处理(直方图计算图像阈值,处理灰度图像,P-tile法,大津法)

本文介绍了如何使用OpenCV库在C++中通过直方图计算、P-Tile法、大津法和局部自适应方法处理灰度图像,包括直方图绘制、二值化处理和图像阈值选择。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

3.1 绘制直方图

//*************************************************************************************
// 函数名称     绘制图像直方图
// 参数说明     image             图像原数组
// 参数说明     hist_scale        要绘制的直方图单个矩形宽
// 参数说明     hist_scale        要绘制的直方图高
// 返回参数     double            图像阈值
// 备注信息     按空格退出
//*************************************************************************************
double img_show_hist(cv::Mat image, int hist_scale, int hist_height, int histSize)
{
    float range[] = { 0, 256 };         // 像素值的范围
    float bin_val, threshold ;
    int intensity;
    const float* histRange = { range };
    double max_val, min_val, peak_val = 0;
    cv::Point min_loc, max_loc;

    // 计算直方图
    cv::Mat hist;
    cv::calcHist(&image, 1, 0, cv::Mat(), hist, 1, &histSize, &histRange, true, false);

    for (int i = 0; i < hist.rows; ++i) {
        float bin_val = hist.at<float>(i);
        std::cout << "Bin " << i << ": " << bin_val << std::endl;
    }
    //创建一个黑底的8位的3通道图像,高256,宽256*2
    Mat hist_img(hist_height, 256 * hist_scale, CV_8UC3, Scalar(0, 0, 0));

    //归一化处理
    normalize(hist, hist, 0, hist_height, NORM_MINMAX, -1, Mat());

    //计算直方图的最大像素值
    minMaxLoc(hist, &min_val, &max_val, &min_loc, &max_loc);
    //遍历直方图得到的数据
    for (int i = 0; i < 256; i++)
    {
        bin_val = hist.at<float>(i);                                //遍历hist元素(注意hist中是float类型)
        intensity = cvRound(bin_val * hist_height / max_val);       //绘制高度
        rectangle(hist_img,
            Point(i * hist_scale, hist_height - 1),
            Point((i + 1) * hist_scale - 1,
                hist_height - intensity),
            Scalar(255, 255, 255));
        //简单地图片杂色干扰过滤,输出阈值
        if (bin_val > peak_val && i > 3)
        {
            peak_val = bin_val;
            threshold = i;
        }
    }
//显示直方图
    cv::imshow("hist", hist_img);
    std::string name = "hist";

    while (waitKey(1) != ' ');
cv::destroyAllWindows();

    std::cout << "threshold = " << threshold << endl;

    return threshold;
}

3.2 P-tile法处理灰度图像

//*************************************************************************************
// 函数名称     P_Tile图像二值化处理
// 参数说明     gray             灰度图像原数组
// 备注信息     
//*************************************************************************************
int P_Tile_Extract(Mat gray)
{
    // 计算前景占比
    int totalPixels = gray.rows * gray.cols;
    int foregroundPixels = cv::countNonZero(gray);

    double percentage = static_cast<double>(foregroundPixels) / totalPixels * 100.0;

    //计算直方图
    std::cout << "percentage = " << percentage << endl;
    std::cout << "Number of channels: " << gray.channels() << endl;
    std::cout << "Image size: " << gray.size() << endl;
   
    float range[] = { 0, 256 }, bin_val, threshold;
    int histSize = 256;
    const float* histRange = { range };

    cv::Mat hist;
    cv::calcHist(&gray, 1, 0, cv::Mat(), hist, 1, &histSize, &histRange, true, false);

    //  P_Tile图像二值化处理
    int amount = 0, sum = 0;
    for (int y = 0; y < hist.rows; y++)
        amount += hist.at<float>(y);
    int y;
    for (y = 0; y < hist.rows; y++)
    {
        sum += hist.at<float>(y);
        if (sum >= amount * percentage / 100) break;
    }

    std::cout << "amount = " << amount << endl;
    std::cout << "sum = " << sum << endl;
    std::cout << "y = " << y << endl;
    return y;
}

3.3 大津法处理灰度图像

3.3.1 彩色图像转灰度图像

//显示灰度图像
  cv::Mat gray;
  cv::cvtColor(im, gray, cv::COLOR_BGR2GRAY);      
  cv::imshow("gray", gray);
  while (waitKey(1) != ' ');
  cv::destroyAllWindows();

3.3.2 大津法处理灰度图像

  // 大津法处理二值化图像
   cv::Mat dst;
   cv::threshold(gray, dst, 0, 255, THRESH_OTSU);
   cv::imshow("dst", dst);
   std::string name = "大津法";
   save_image(dst, root, name);
   while (waitKey(1) != ' ');
   cv::destroyAllWindows();

3.4 局部自适应法处理灰度图像

/ 局部自适应二值化图像处理
 Mat src_binary;
 adaptiveThreshold(~gray, src_binary, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 11, -2);
 cv::imshow("src_binary", src_binary);
 name = "局部自适应";
 save_image(src_binary, root, name);
 while (waitKey(1) != ' ');
 cv::destroyAllWindows();

3.5 直方图计算图像阈值,处理灰度图像

// 绘制图像直方图
double max_val = img_show_hist(gray, 4, 256, 256);        
//显示二值图像         
cv::cvtColor(im, gray, cv::COLOR_BGR2GRAY);

cv::threshold(gray, binary_gray, max_val, 256, THRESH_BINARY);
cv::imshow("binary_gray", binary_gray);

while (waitKey(1) != ' ');
cv::destroyAllWindows();

3.6 保存所需图像

//*************************************************************************************
// 函数名称     保存图像
// 参数说明     img             图像原数组
// 参数说明     &file_root            生成文件目录
// 参数说明     string &name          生成文件名称
// 返回参数     void
// 备注信息     
//使用示例      std::string name = "gray_img";  save_image(gray, root, name);
//*************************************************************************************
/* 创建处理图像BMP文件 */
#define ENABLE_MAKE_IMG     (1)

void save_image(Mat img, const string& file_root, string& name)
{
#if ENABLE_MAKE_IMG
    // 生成文件名
    std::string extract_path = file_root + "/"  + name + ".bmp";
    // 保存图像
    cv::imwrite(extract_path, img);
#endif
}

3.7 实验数据记录(以图2-1为例)

图3- 1 绘制直方图
图3- 1 绘制直方图
图3- 2 P-tile法处理灰度图像
图3- 2 P-tile法处理灰度图像
图3- 3 大津法处理灰度图像
图3- 3 大津法处理灰度图像
图3- 4 局部自适应法处理灰度图像
图3- 4 局部自适应法处理灰度图像
图3- 5 直方图计算图像阈值,处理灰度图像
图3- 5 直方图计算图像阈值,处理灰度图像

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值