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技术站