opencv图像处理学习(六十二)——寻找波峰与获取最佳阈值

1.寻找波峰

原理后面再补,先上代码:

cv::Mat findpeakmax(cv::Mat srcImage, std::vector<int>& resultVec)//求波峰
{
	cv::Mat value;//返回投影向量

	cv::Mat VerMat;
	cv::Mat resMat = srcImage.clone();

	//阈值化操作
	int thresh = 130;
	int threshType = 0;
	//预设最大值
	const int maxVal = 255;
	//固定阈值化操作
	cv::threshold(srcImage, srcImage, thresh, maxVal, threshType);
	srcImage.convertTo(srcImage, CV_32FC1);
	//计算垂直投影
	cv::reduce(srcImage, VerMat, 0, CV_REDUCE_SUM);
	//遍历求差分符号
	float *iptr = ((float*)VerMat.data) + 1;
	std::vector<int> tempVec(VerMat.cols - 1, 0);

	for (int i = 1; i < VerMat.cols - 1; ++i, ++iptr)
	{
		if (*(iptr + 1) - *iptr > 0)
		{
			tempVec[i] = 1;
		}

		else if (*(iptr + 1) - *iptr < 0)
		{
			tempVec[i] = -1;
		}

		else
		{
			tempVec[i] = 0;
		}
	}
	//对符号函数进行遍历
	for (int i = tempVec.size() - 1; i >= 0; i--)
	{
		if (tempVec[i] == 0 && tempVec.size() - 1)
		{
			tempVec[i] = 1;
		}

		else if (tempVec[i] == 0)
		{
			if (tempVec[i + 1] >= 0)
			{
				tempVec[i] = 1;
			}

			else
			{
				tempVec[i] = -1;
			}
		}
	}

	//波峰判断输出
	for (std::vector<int>::size_type i = 0; i != tempVec.size() - 1; i++)
	{
		if (tempVec[i + 1] - tempVec[i] == -2)//+2为波谷
		{
			resultVec.push_back(i + 1);
		}
	}

	//输出波峰位置
	for (int i = 0; i < resultVec.size(); i++)
	{
		for (int ii = 0; ii < resMat.rows; ++ii)
		{
			resMat.at<unsigned char>(ii, resultVec[i]) = 255;
		}
	}

	value = VerMat;
	return value;
}

2.寻找最佳阈值:

原理后面再补,先上代码:

#pragma region 寻找最佳阈值函数-Get_IterationThres
int Get_IterationThres(cv::Mat Img)
{
	/************************绘制直方图****************************/
	const int channels[1] = { 0 };
	//直方图的每一个维度的 柱条的数目(就是将灰度级分组)  
	int histSize[] = { 256 };   //如果这里写成int histSize = 256;   那么下面调用计算直方图的函数的时候,该变量需要写 &histSize  
								//定义一个变量用来存储 单个维度 的数值的取值范围    
	float midRanges[] = { 0, 256 };
	//确定每个维度的取值范围,就是横坐标的总数    
	const float *ranges[] = { midRanges };
	//输出的结果存储的 空间 ,用MatND类型来存储结果  
	cv::MatND dstHist;
	double* HistGram = new double[256];
	calcHist(&Img, 1, channels, cv::Mat(), dstHist, 1, histSize, ranges, true, false);
	for (int i = 0; i < 256; i++)
	{
		HistGram[i] = dstHist.at<float>(i);
	}
	int X, Iter = 0;
	int MeanValueOne, MeanValueTwo, SumOne, SumTwo, SumIntegralOne, SumIntegralTwo;
	int MinValue, MaxValue;
	int NewThreshold;

	for (MinValue = 0; MinValue < 256 && HistGram[MinValue] == 0; MinValue++);
	{
		for (MaxValue = 255; MaxValue > MinValue && HistGram[MinValue] == 0; MaxValue--);
		{
			if (MaxValue == MinValue)
				return MaxValue;          // 图像中只有一个颜色             
			if (MinValue + 1 == MaxValue)
				return MinValue;      // 图像中只有二个颜色
		}
	}
	int IterationThres = MinValue;
	NewThreshold = (MaxValue + MinValue) >> 1;//NewThreshold为灰度最大最小值的平均值
	while (IterationThres != NewThreshold)//当前后两次迭代获得阈值相同时,结束迭代    
	{
		SumOne = 0;
		SumIntegralOne = 0;
		SumTwo = 0;
		SumIntegralTwo = 0;
		IterationThres = NewThreshold;
		for (X = MinValue; X <= IterationThres; X++)//根据阈值将图像分割成目标和背景两部分,求出两部分的平均灰度值      
		{
			SumIntegralOne += HistGram[X] * X;
			SumOne += HistGram[X];
		}
		MeanValueOne = SumIntegralOne / SumOne;
		for (X = IterationThres + 1; X <= MaxValue; X++)
		{
			SumIntegralTwo += HistGram[X] * X;
			SumTwo += HistGram[X];
		}
		if (SumTwo == 0)
		{
			NewThreshold = MeanValueOne;
		}
		else
		{
			MeanValueTwo = SumIntegralTwo / SumTwo;
			NewThreshold = (MeanValueOne + MeanValueTwo) >> 1;//求出新的阈值
		}
		Iter++;
		if (Iter >= 1000)
			return -1;
	}
	return IterationThres;
}

 

  • 0
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
使用OpenCV库可以很容易地实现车牌图像的阈值化操作,获得二值化图。 以下是基本的代码实现: ```python import cv2 # 读取车牌图像 img = cv2.imread('plate.jpg') # 转换为灰度图像 gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 自适应二值化处理 thresh_img = cv2.adaptiveThreshold(gray_img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2) # 显示二值化图像 cv2.imshow("Thresholded Image", thresh_img) cv2.waitKey(0) cv2.destroyAllWindows() ``` 在上述代码中,使用了OpenCV自适应阈值处理函数 `cv2.adaptiveThreshold()`,该函数会根据图像的局部像素特征来自动调整二值化阈值,从而得到更好的二值化效果。其中,`gray_img` 是原始车牌图像的灰度图像,`thresh_img` 是通过自适应阈值处理得到的二值化图像。 在调用 `cv2.adaptiveThreshold()` 函数时,需要指定以下几个参数: - `gray_img`:输入的灰度图像。 - `255`:输出的二值化图像像素值的最大值。 - `cv2.ADAPTIVE_THRESH_GAUSSIAN_C`:自适应阈值处理方法,这里采用的是高斯加权平均法。 - `cv2.THRESH_BINARY`:二值化类型,这里采用的是简单的二值化。 - `11`:像素邻域大小,表示当前像素的阈值会根据周围 11×11 个像素的灰度值自适应地调整。 - `2`:常数 C,表示在计算当前像素阈值时需要加上的常数。 最终得到的二值化图像可以通过 `cv2.imshow()` 函数进行显示,其中 `"Thresholded Image"` 是窗口的名称,可以根据需要进行修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值