C++ OpenCV单峰三角阈值法Thresh_Unimodal详解

yizhihongxing

C++ OpenCV单峰三角阈值法Thresh_Unimodal详解

介绍

本文主要讲解C++ OpenCV单峰三角阈值法Thresh_Unimodal的实现原理和使用方法。

单峰三角阈值法是一种图像二值化的方法,能够快速地将图像转换为黑白二值图像。

原理

单峰三角阈值法的实现原理是先对归一化直方图进行平滑处理,然后利用三角函数寻找直方图的峰值。找到峰值后,峰值位置的灰度值就可以作为阈值进行二值化。

代码实现

OpenCV库提供了cv::threshold函数用于图像的二值化处理,其中,第二个参数就是阈值。而使用单峰三角阈值法的话,阈值可以通过下面的代码进行计算。

double get_unimodal_threshold(cv::Mat& src) {
    cv::Mat hist;
    float range[] = {0, 256};
    const float* histRange = {range};
    int histSize = 256;
    cv::calcHist(&src, 1, 0, cv::Mat(), hist, 1, &histSize, &histRange, true, false);

    cv::Mat kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(5, 5));
    cv::morphologyEx(hist, hist, cv::MORPH_CLOSE, kernel);

    int max_idx = 0;
    float max_val = hist.at<float>(0);
    const float* hist_data = hist.ptr<float>(0);
    for (int i = 1; i < histSize; i++) {
        if (hist_data[i] > max_val) {
            max_idx = i;
            max_val = hist_data[i];
        }
    }

    double mult = 0.33;
    int left_idx = max_idx;
    while (left_idx > 0 && hist_data[left_idx] > mult * max_val)
        left_idx--;

    int right_idx = max_idx;
    while (right_idx < histSize - 1 && hist_data[right_idx] > mult * max_val)
        right_idx++;

    return (double)(left_idx + right_idx) / 2.0;
}

代码中会先求出原始图像的直方图,并对其进行平滑处理。然后在直方图上寻找峰值,并计算出阈值。

示例说明

假设需要将一张图像进行二值化处理,代码如下:

cv::Mat src = cv::imread("image.jpg", cv::IMREAD_GRAYSCALE);
cv::Mat dst;
double thresh = get_unimodal_threshold(src);
cv::threshold(src, dst, thresh, 255, cv::THRESH_BINARY);
cv::imshow("binary", dst);
cv::waitKey(0);

在上面代码中,src是输入的灰度图像,dst是输出的二值化图像。使用get_unimodal_threshold函数求得阈值,然后调用cv::threshold函数进行二值化,最后调用cv::imshow函数将结果显示出来。

另外,本文提供一个简单的测试程序,可以测试单峰三角阈值法的性能。测试程序如下:

#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
#include <ctime>

double get_unimodal_threshold(cv::Mat& src);

int main(int argc, char* argv[]) {
    if (argc < 2) {
        std::cerr << "usage: " << argv[0] << " <image>" << std::endl;
        return 1;
    }

    cv::Mat src = cv::imread(argv[1], cv::IMREAD_GRAYSCALE);
    if (src.empty()) {
        std::cerr << "failed to open image: " << argv[1] << std::endl;
        return 1;
    }

    clock_t begin = clock();
    double thresh = get_unimodal_threshold(src);
    clock_t end = clock();

    std::cout << "time used: " << double(end - begin) / CLOCKS_PER_SEC << std::endl;
    std::cout << "threshold: " << thresh << std::endl;

    return 0;
}

运行测试程序时需要指定输入的图像文件,测试程序将会输出单峰三角阈值法计算阈值的时间和结果。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++ OpenCV单峰三角阈值法Thresh_Unimodal详解 - Python技术站

(0)
上一篇 2023年5月24日
下一篇 2023年5月24日

相关文章

  • 聊聊python的gin库的介绍和使用

    聊聊Python的gin库的介绍和使用 什么是gin库 gin库是由Google开发的一个工具库,主要用于依赖注入和参数配置。它提供了一种简单的方式来对Python应用程序进行配置和管理。 gin库的安装 可以通过pip来安装gin库,其命令如下所示: pip install gin-config gin库的基本使用 1. 使用字符串进行配置 可以使用字符串…

    人工智能概览 2023年5月25日
    00
  • C#基于时间轮调度实现延迟任务详解

    C#基于时间轮调度实现延迟任务详解 什么是时间轮调度 时间轮是一个计算机算法中的概念,用于实现时间驱动的操作。时间轮调度算法通过预先设置一定数量的槽位,每个槽位对应一段时间,然后在这些槽位中放置要执行的任务,根据时间轮的不断滚动,任务可以在指定的时间段内得到执行。在C#中,我们可以通过Timer类实现时间轮调度。 定义延迟任务 我们可以定义一个延迟任务的抽象…

    人工智能概览 2023年5月25日
    00
  • Ubuntu20.04安装cuda10.1的步骤(图文教程)

    下面是Ubuntu20.04安装cuda10.1的步骤详细攻略: 1. 准备工作 操作系统:Ubuntu 20.04 显卡驱动:建议使用官方推荐驱动或更高版本 CUDA版本:CUDA 10.1 2. 下载并安装CUDA Toolkit 首先从Nvidia官网上下载CUDA Toolkit 10.1,可以通过WGET命令或浏览器下载,这里以WGET命令为例: …

    人工智能概论 2023年5月24日
    00
  • Linux-ubuntu16.04 Python3.5配置OpenCV3.2的方法

    我来详细讲解“Linux-Ubuntu16.04 Python3.5配置OpenCV3.2的方法”。 步骤一:安装必要的依赖 在终端中执行以下命令,安装OpenCV3.2所需的依赖项: sudo apt-get update sudo apt-get install build-essential cmake pkg-config sudo apt-get …

    人工智能概览 2023年5月25日
    00
  • 详解微信小程序自定义组件的实现及数据交互

    下面我给出详解微信小程序自定义组件的实现及数据交互的完整攻略。内容分为以下几部分: 自定义组件的概念及基本用法 自定义组件的实现步骤 自定义组件与页面的数据交互 示例说明 1. 自定义组件的概念及基本用法 自定义组件是一种可以重复使用的自定义元素,由类似视图和逻辑的 WXML, WXSS 和 JS 结合而成。一般情况下,自定义组件的结构是由: wxml 文件…

    人工智能概论 2023年5月25日
    00
  • 浅谈SpringBoot资源初始化加载的几种方式

    浅谈SpringBoot资源初始化加载的几种方式 在SpringBoot应用中,如果需要在应用启动时加载一些资源,例如配置文件、数据库表结构等等,我们可以采取以下几种方式。 方式一:使用SpringBoot的ApplicationRunner或CommandLineRunner接口 在SpringBoot应用中,如果希望在启动时完成一些初始化的工作,可以实现…

    人工智能概论 2023年5月25日
    00
  • 详解model.train()和model.eval()两种模式的原理与用法

    详解model.train()和model.eval()两种模式的原理与用法 在PyTorch中,训练过程和评估过程存在不同的模式。这两种模式分别由model.train()和model.eval()方法控制,在训练和评估深度学习模型时,这两种模式之间的切换非常重要。 model.train()的原理和用法 当我们在训练模型时,我们可以使用model.tra…

    人工智能概论 2023年5月25日
    00
  • Django如何开发简单的查询接口详解

    当开发Django应用程序时,创建API接口是很常见的一步。API接口允许第三方应用访问你的应用程序数据。在本文中,我们将介绍如何开发一个简单的查询接口。 第一步:创建Django项目和应用 首先,需要创建Django项目和应用。可以通过以下指令来完成: $ django-admin startproject projectname $ python man…

    人工智能概论 2023年5月25日
    00
合作推广
合作推广
分享本页
返回顶部