OpenCV学习 基础图像操作(七):水平与水直线条提取、验证码去背景

PS:本篇通过两个小的案例,来示范下形态学操作在图像处理过程中的应用。

提取一副图片中的水平线和水直线

AIP介绍

自适应阈值分割

void adaptiveThreshold(InputArray src, OutputArray dst,  
                        double maxValue, int adaptiveMethod,  
                       int thresholdType, int bolckSize, double C)  

参数1:InputArray类型的src,输入图像,填单通道,单8位浮点类型Mat即可。
参数2:函数运算后的结果存放在这。即为输出图像(与输入图像同样的尺寸和类型)。
参数3:预设满足条件的最大值,普通图像为255。
参数4:指定自适应阈值算法。可选择ADAPTIVE_THRESH_MEAN_C 或 ADAPTIVE_THRESH_GAUSSIAN_C两种。
参数5:指定阈值类型。可选择THRESH_BINARY或者THRESH_BINARY_INV两种。(即二进制阈值或反二进制阈值)。
参数6:表示邻域块大小,用来计算区域阈值,选用奇数。
参数7:参数C表示与算法有关的参数,它是一个从均值或加权均值提取的常数,可以是负数。

ADAPTIVE_THRESH_MEAN_C,为局部邻域块的平均值,该算法是先求出块中的均值,再减去常数C。

ADAPTIVE_THRESH_GAUSSIAN_C,为局部邻域块的高斯加权和。该算法是在区域中(x, y)周围的像素根据高斯函数按照他们离中心点的距离进行加权计算,再减去常数C。

流程与思路

  • 首先将图片转换为灰度图片

  • 使用自适应阈值分割,将图片处理为二至图片(注意:前景比背景暗时,对前景处理应使用闭操作;前景比背景亮时,对前景处理应使用开操作);

  • 设计运算核用于提取在横向和纵向的连通线条:
    • 如提取横向水平线条,则核的形状应为Size(5,1);如提取竖向垂直线条,则核的形状应为Size(1,5)。总之,所要提取的方向上,核的应大于另一个方向。
    • 提取方向上,核的跨度越大,则提取的程度越高,即要求该方向上的连通程度比较高才会被提取出来。
    • 非提取方向上,设为“1”,保证隔断另一个方向连通性对提取方向的干扰。

代码与实践

#include <iostream>
#include <math.h>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

int main(int argc, char* argv[])
{
	//src = imread("src.jpg");
	Mat src = imread("1.PNG");
	if (!src.data)
	{
		cout << "cannot open image" << endl;
		return -1;
	}
	namedWindow("input image", WINDOW_AUTOSIZE);
	imshow("input image",src);
	
	Mat gray;
	cvtColor(src,gray ,COLOR_BGR2GRAY);
	imshow("gray", gray);
	adaptiveThreshold(gray, gray, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 15, 10);
	imshow("bineray", gray);
	
	Mat Hline = getStructuringElement(MORPH_RECT, Size(1, 5), Point(-1, -1));
	Mat Vline = getStructuringElement(MORPH_RECT, Size(5, 1), Point(-1, -1));
	Mat H_res, V_res;

	morphologyEx(gray,H_res,MORPH_CLOSE,Hline);
	morphologyEx(gray,V_res,MORPH_CLOSE,Vline);

	imshow("H-res", H_res);
	imshow("V-res", V_res);

	waitKey(0);
	return 0;
}

去除验证码图片中的背景干扰

流程与思路(参照上面的例子)

  • 首先将图片转换为灰度图片
  • 使用自适应阈值分割,将图片处理为二至图片(注意:前景比背景暗时,对前景处理应使用闭操作;前景比背景亮时,对前景处理应使用开操作);
  • 根据噪点的大小,来调节运算核的大小,让其可以滤除背景干扰,却又保存字符的连通性。一般核大小的长宽比与验证码图片的长宽比相同较为合适。否则应根据实际情况进行调节,保证运算核在保持字符连通性时,尽量大,越大对噪声的滤除也越强。

代码与实践

#include <iostream>
#include <math.h>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

int main(int argc, char* argv[])
{
	
	Mat src = imread("chars.png");
	if (!src.data)
	{
		cout << "cannot open image" << endl;
		return -1;
	}
	namedWindow("input image", WINDOW_AUTOSIZE);
	imshow("input image",src);
	
	Mat gray;
	cvtColor(src,gray ,COLOR_BGR2GRAY);
	imshow("gray", gray);
	adaptiveThreshold(gray, gray, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 15, 10);
	imshow("bineray", gray);
	
	Mat Kernel = getStructuringElement(MORPH_RECT, Size(3, 5), Point(-1, -1));
        //改变核在总想和横向的范围,来保证字符的连通性
	Mat Result;
	morphologyEx(gray,Result,MORPH_CLOSE,Kernel);

	imshow("Result", Result);

	waitKey(0);
	return 0;
}

扫描二维码关注公众号,回复: 12039909 查看本文章

猜你喜欢

转载自blog.csdn.net/fan1102958151/article/details/107092562
今日推荐