基于opencv的c++图像处理(图像二值化)

这篇具有很好参考价值的文章主要介绍了基于opencv的c++图像处理(图像二值化)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

基于opencv的c++接口,实现常用的图像二值化方法,包括了最大类间方差法(OTSU)、固定化阈值以及自适应阈值。

相关的opencv接口解析

CV_EXPORTS_W double threshold( InputArray src, OutputArray dst,
                               double thresh, double maxval, int type );

该函数将固定级别的阈值应用于多通道阵列。该函数通常用于从灰度图像中获取双层(二进制)图像(#compare 也可用于此目的)或用于去除噪声,即过滤掉值过小或过大的像素.该函数支持几种类型的阈值。它们由类型参数确定。
此外,特殊值#THRESH_OTSU 或#THRESH_TRIANGLE 可以与上述值之一组合。在这些情况下,该函数使用 Otsu 或 Triangle 算法确定最佳阈值,并使用它代替指定的阈值。

@param src 输入数组(多通道、8 位或 32 位浮点)。
@param dst 与 src 具有相同大小和类型以及相同通道数的输出数组。
@param thresh 阈值。
@param maxval 与 #THRESH_BINARY 和 #THRESH_BINARY_INV 阈值类型一起使用的最大值。
@param type 阈值类型(请参阅#ThresholdTypes)。
@return 如果使用 Otsu 或 Triangle 方法,则计算阈值。

enum ThresholdTypes {
    THRESH_BINARY     = 0, //!< \f[\texttt{dst} (x,y) =  \fork{\texttt{maxval}}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{0}{otherwise}\f]
    THRESH_BINARY_INV = 1, //!< \f[\texttt{dst} (x,y) =  \fork{0}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{\texttt{maxval}}{otherwise}\f]
    THRESH_TRUNC      = 2, //!< \f[\texttt{dst} (x,y) =  \fork{\texttt{threshold}}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{\texttt{src}(x,y)}{otherwise}\f]
    THRESH_TOZERO     = 3, //!< \f[\texttt{dst} (x,y) =  \fork{\texttt{src}(x,y)}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{0}{otherwise}\f]
    THRESH_TOZERO_INV = 4, //!< \f[\texttt{dst} (x,y) =  \fork{0}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{\texttt{src}(x,y)}{otherwise}\f]
    THRESH_MASK       = 7,
    THRESH_OTSU       = 8, //!< flag, use Otsu algorithm to choose the optimal threshold value
    THRESH_TRIANGLE   = 16 //!< flag, use Triangle algorithm to choose the optimal threshold value
};
CV_EXPORTS_W void adaptiveThreshold( InputArray src, OutputArray dst,
                                     double maxValue, int adaptiveMethod,
                                     int thresholdType, int blockSize, double C );

对数组应用自适应阈值。该函数根据公式将灰度图像转换为二值图像:

  • THRESH_BINARY
    \f[dst(x,y) = \fork{\texttt{maxValue}}{如果 (src(x,y) > T(x,y))}{0}{否则}\f]
  • THRESH_BINARY_INV
    \f[dst(x,y) = \fork{0}{如果 (src(x,y) > T(x,y))}{\texttt{maxValue}}{否则}\f]
    其中 \fKaTeX parse error: Undefined control sequence: \f at position 7: T(x,y)\̲f̲ 是为每个像素单独计算的阈值(请参阅 AdaptiveMethod 参数)。
    该函数可以就地处理图像。
    @param src 源 8 位单通道图像。
    @param dst 与 src 大小和类型相同的目标图像。
    @param maxValue 分配给满足条件的像素的非零值
    @param AdaptiveMethod 要使用的自适应阈值算法,请参阅#AdaptiveThresholdTypes。
    #BORDER_REPLICATE | #BORDER_ISOLATED 用于处理边界。
    @param thresholdType 阈值类型,必须是#THRESH_BINARY 或#THRESH_BINARY_INV,请参阅#ThresholdTypes。
    @param blockSize 用于计算像素阈值的像素邻域的大小:3、5、7 等。
    @param C 从平均值或加权平均值中减去常数。通常,它是正数,但也可能为零或负数。
enum AdaptiveThresholdTypes {
    /** the threshold value \f$T(x,y)\f$ is a mean of the \f$\texttt{blockSize} \times
    \texttt{blockSize}\f$ neighborhood of \f$(x, y)\f$ minus C */
    ADAPTIVE_THRESH_MEAN_C     = 0,
    /** the threshold value \f$T(x, y)\f$ is a weighted sum (cross-correlation with a Gaussian
    window) of the \f$\texttt{blockSize} \times \texttt{blockSize}\f$ neighborhood of \f$(x, y)\f$
    minus C . The default sigma (standard deviation) is used for the specified blockSize . See
    #getGaussianKernel*/
    ADAPTIVE_THRESH_GAUSSIAN_C = 1
};

示例代码

binarizate.h

#pragma once
#include <iostream>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\core\core.hpp>
#include <opencv2\imgproc\imgproc.hpp>

using namespace std;
using namespace cv;
#define PROCESS_IMG_SUCESS 0
#define PROCESS_IMG_FAIL 1

namespace ImgEnhance
{
	//二值化
	class Binarizate
	{

	public:
		Binarizate() { cout << "Binarizate is being created" << endl; } // 这是构造函数声明
		~Binarizate() { cout << "Binarizate is being deleted" << endl; } // 这是析构函数声明

		int OTSU(cv::Mat srcImage);// 大律法函数实现
		int OtsuBinarizate(cv::Mat srcImage, cv::Mat &dstImage, int maxVal, int threshType);//大律法二值化
		int FixedBinarizate(cv::Mat srcImage, cv::Mat &dstImage, int thresh, int maxVal, int threshType);//固定化阈值
		int AdaptiveBinarizate(cv::Mat srcImage, cv::Mat &dstImage, int maxVal, int adaptiveMethod, int thresholdType, int blockSize, int constValue);//自适应阈值化

	};
}

binarizate.cpp

#include "binarizate.h"

int ImgEnhance::Binarizate::OTSU(cv::Mat srcImage)
{
	int nCols = srcImage.cols;
	int nRows = srcImage.rows;
	int threshold = 0;
	// 初始化统计参数
	int nSumPix[256];
	float nProDis[256];
	for (int i = 0; i < 256; i++)
	{
		nSumPix[i] = 0;
		nProDis[i] = 0;
	}
	// 统计灰度级中每个像素在整幅图像中的个数 
	for (int i = 0; i < nCols; i++)
	{
		for (int j = 0; j < nRows; j++)
		{
			nSumPix[(int)srcImage.at<uchar>(i, j)]++;
		}
	}
	// 计算每个灰度级占图像中的概率分布
	for (int i = 0; i < 256; i++)
	{
		nProDis[i] = (float)nSumPix[i] / (nCols * nRows);
	}
	// 遍历灰度级[0,255],计算出最大类间方差下的阈值  
	float w0, w1, u0_temp, u1_temp, u0, u1, delta_temp;
	double delta_max = 0.0;
	for (int i = 0; i < 256; i++)
	{
		// 初始化相关参数
		w0 = w1 = u0_temp = u1_temp = u0 = u1 = delta_temp = 0;
		for (int j = 0; j < 256; j++)
		{
			//背景部分 
			if (j <= i)
			{
				// 当前i为分割阈值,第一类总的概率  
				w0 += nProDis[j];
				u0_temp += j * nProDis[j];
			}
			//前景部分   
			else
			{
				// 当前i为分割阈值,第一类总的概率
				w1 += nProDis[j];
				u1_temp += j * nProDis[j];
			}
		}
		// 分别计算各类的平均灰度 
		u0 = u0_temp / w0;
		u1 = u1_temp / w1;
		delta_temp = (float)(w0 *w1* pow((u0 - u1), 2));
		// 依次找到最大类间方差下的阈值    
		if (delta_temp > delta_max)
		{
			delta_max = delta_temp;
			threshold = i;
		}
	}
	return threshold;
}

int ImgEnhance::Binarizate::OtsuBinarizate(cv::Mat srcImage, cv::Mat &dstImage, int maxVal, int threshType)
{
	if (!srcImage.data || srcImage.channels() != 1)
	{
		return 1;
	}
	// 初始化阈值参数
	int thresh = OTSU(srcImage);
	// 初始化阈值化处理的类型 
	/* 0: 二进制阈值 1: 反二进制阈值 2: 截断阈值
	3: 0阈值   4: 反0阈值*/
	//int threshType = 0;
	// 预设最大值
	//const int maxVal = 255;
	// 固定阈值化操作
	cv::threshold(srcImage, dstImage, thresh,
		maxVal, threshType);
	return 0;

}

int ImgEnhance::Binarizate::FixedBinarizate(cv::Mat srcImage, cv::Mat &dstImage, int thresh, int maxVal, int threshType)
{
	if (!srcImage.data || srcImage.channels() != 1)
	{
		return 1;
	}
	// 初始化阈值参数
	//int thresh = 130;
	// 初始化阈值化处理的类型 
	/* 0: 二进制阈值 1: 反二进制阈值 2: 截断阈值
	3: 0阈值   4: 反0阈值 8:大均法*/
	//int threshType = 0;
	// 预设最大值
	//const int maxVal = 255;
	// 固定阈值化操作
	cv::threshold(srcImage, dstImage, thresh,
		maxVal, threshType);
	return 0;
}

int ImgEnhance::Binarizate::AdaptiveBinarizate(cv::Mat srcImage, cv::Mat &dstImage, int maxVal, int adaptiveMethod, int thresholdType, int blockSize, int constValue)
{
	if (!srcImage.data || srcImage.channels() != 1)
	{
		return 1;
	}
	// 初始化自适应阈值参数
	//int blockSize = 5;
	//int constValue = 10;
	//const int maxVal = 255;
	/* 自适应阈值算法
	0:ADAPTIVE_THRESH_MEAN_C
	1: ADAPTIVE_THRESH_GAUSSIAN_C
	阈值类型
	0: THRESH_BINARY
	1: THRESH_BINARY_INV */
	//int adaptiveMethod = 0;
	//int thresholdType = 1;
	// 图像自适应阈值操作
	cv::adaptiveThreshold(srcImage, dstImage, maxVal, adaptiveMethod, thresholdType, blockSize, constValue);
	return 0;
}

test.cpp

#include"binarizate.h"

ImgEnhance::Binarizate ImgB;//二值化

int main()
{
	// 读取源图像及判断
	cv::Mat srcImage = cv::imread("flower.jpg");
	if (!srcImage.data)
	{
		return 1;
	}
	/*cv::namedWindow("原始图", 0);
	cv::imshow("原始图", srcImage);*/
	// 转化为灰度图像
	cv::Mat srcGray;
	if (srcImage.channels() == 3)
	{
		cv::cvtColor(srcImage, srcGray, COLOR_RGB2GRAY);
	}
	else
	{
		srcGray = srcImage.clone();
	}
	cv::namedWindow("灰度图", 0);
	cv::imshow("灰度图", srcGray);


	//最大类间方差二值化(OTSU)
	Mat otsuImage;
	const int maxVal = 255;
	int threshType = 0;
	// 初始化阈值化处理的类型 
	/* 0: 二进制阈值 1: 反二进制阈值 2: 截断阈值
	3: 0阈值   4: 反0阈值*/
	ImgB.OtsuBinarizate(srcGray, otsuImage, maxVal, threshType);
	cv::namedWindow("otsu二值化图", 0);
	cv::imshow("otsu二值化图", otsuImage);

	//固定化阈值
	Mat fixedImage;
	int thresh = 100;
	int threshType2 = 0;
	ImgB.FixedBinarizate(srcGray, fixedImage, thresh, maxVal, threshType2);//固定化阈值
	cv::namedWindow("固定阈值二值化图", 0);
	cv::imshow("固定阈值二值化图", fixedImage);

	//自适应阈值化
	// 初始化自适应阈值参数
	Mat adaptiveImage;
	int blockSize = 5;
	int constValue = 10;
	//const int maxVal = 255;
	/* 自适应阈值算法
	0:ADAPTIVE_THRESH_MEAN_C
	1: ADAPTIVE_THRESH_GAUSSIAN_C
	阈值类型
	0: THRESH_BINARY
	1: THRESH_BINARY_INV */
	int adaptiveMethod = ADAPTIVE_THRESH_GAUSSIAN_C;
	int thresholdType = 0;
	ImgB.AdaptiveBinarizate(srcGray, adaptiveImage, maxVal, adaptiveMethod, thresholdType, blockSize, constValue);
	cv::namedWindow("自适应阈值-高斯二值化图", 0);
	cv::imshow("自适应阈值-高斯二值化图", adaptiveImage);

	cv::waitKey(0);

	return 0;

}

结果展示

基于opencv的c++图像处理(图像二值化)文章来源地址https://www.toymoban.com/news/detail-466576.html

到了这里,关于基于opencv的c++图像处理(图像二值化)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C#使用OpenCv(OpenCVSharp)图像全局二值化处理实例

    本文实例演示C#语言中如何使用OpenCv(OpenCVSharp)对图像进行全局二值化处理。 目录 图像二值化原理 函数原型 参数说明 实例 效果

    2024年02月13日
    浏览(34)
  • OpenCV-Python学习(10)—— OpenCV 图像二值化处理(cv.threshold)

    1. 学习目标 理解图像的分类,不同类型的图像的区别; 对图像进行二值化处理,对【 cv.threshold 】函数的理解。 2. 图像分类 2.1 不同类型图像说明 按照颜色对图像进行分类,可以分为二值图像、灰度图像和彩色图像。 二值图像: 只有黑色和白色两种颜色的图像。 每个像素

    2024年02月03日
    浏览(39)
  • [2] 图像处理之----二值化处理

    简单阈值是选取一个全局阈值,然后把整幅图像分成非黑即白的二值图像,灰度值大于阈值就赋为255反之为0。 ret,mask = cv2.threshold(img2gray,175,255,cv2.THRESH_BINAR) 返回值一: 阈值,(Otsu‘s二值化会用到) 返回值二: 处理以后的图像 参数一: 初始图像 参数二:我们自己设定的阈

    2024年02月05日
    浏览(36)
  • MATLAB 图像处理 (二值化,image图片黑白处理)

    Q: MATLAB如何将图片进行 二值化 ,并将 二值化后图片 中的 黑色变成白色 , 原本的白色保持不变,黑白之间的黑色轮廓保持不变。 A: 使用 MATLAB 中的 imbinarize 函数 进行图片二值化。将指定阈值以下的像素值设为 0,其他像素值设为 1。 然后可以使用逻辑取反运算符 ~ (波浪线

    2023年04月08日
    浏览(28)
  • FPGA|数字图像处理实现口罩识别——二值化

    【写在前面】刚入门小菜鸟,记录一下口罩识别学习过程。参考文件和网址会在文末注明。有错误欢迎指出,也欢迎进行补充~ 原理图如下,二值化对应为红框里的部分 使用的二值化方法是 手动指定一个 阈值 ,通过阈值来进行二值化处理 。(还有一种方法是一个自适应阈值

    2023年04月11日
    浏览(34)
  • python图像处理实战(二)—二值化图像与线性变换

    🚀写在前面🚀 🖊个人主页:https://blog.csdn.net/m0_52051577?type=blog  🎁欢迎各位大佬支持点赞收藏,三连必回!! 🔈本人新开系列专栏—python图像处理 ❀愿每一个骤雨初晴之时,所有的蜻蜓振翅和雨后惊雷,都归你。 前言         首先引入以下灰度变换的概念。      

    2024年02月07日
    浏览(35)
  • 二、FPGA实时图像处理(灰度转换、高斯滤波、二值化和边缘检测)

    基于图像实时采集系统实现图像处理 算法:采用精度为7的心理学公式:Gray = R 0.299 + G 0.587 + B 0.114, Gray = R 38 + G 75 + B 15 7 采用sobel算子进行边缘检测。 可以通过参数定义修改二值化和边缘检测阈值,以及控制是否进行图像处理和图像处理类型选择。 高斯滤波效果不明显不做演

    2024年02月11日
    浏览(37)
  • 图像二值化处理(全局阈值 自适应阈值 手动阈值操作以及直方图画法)

    图像二值化就是把让图像的像素点只有0和1(只有黑白两各种颜色,黑是背景,白是前景),关键点是寻找一个阈值T,使图像中小于阈值T的像素点变为0,大于T的像素点变为255。下面介绍的就是寻找一个图像的阈值T的方法。(主要根据直方图) retval:返回的阈值(double类型)

    2024年02月08日
    浏览(41)
  • 使用OpenCV C++进行图像二值化操作

    threshold()将固定阈值应用于多通道图像阵列,通常用于从灰度图像中获得二值图像或用于去除噪声,即滤除值过小或过大的像素。该函数支持几种类型的阈值设置,它们由类型参数决定。 src:输入数组(多通道,8位或32位浮点数) dst:输出数组(与src的尺寸、类型、通道数相

    2024年02月03日
    浏览(31)
  • opencv-图像处理基础-二值图像

    1.二值图像 二值图像是指仅仅包含黑色和白色两种颜色的图像。 在计算机中,通过一个栅格状排列的数据集(矩阵)来表示和处理图像。例如,图 2-1 是 一个字母 A 的图像,计算机在处理该图像时,会首先将其划分为一个个的小方块,每一个小方 块就是一个独立的处理单位

    2024年02月15日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包