图像细化
图像细化是将图像的线条从多像素宽度减少到单位像素宽度的过程,有时又称为“骨架化”或者“中轴变化”
图像细化是模式识别领域重要的出来步骤之一,常用在文字识别中,因为其可以有效将文字细化,增加文字的可识别度
并且能够有效地减少数据量,降低图像的存储难度
图像细化一般要求细化后骨架的连通性、对原图像的细节特征要有较好保留、线条的端点保留完好的同时线条交叉点不能发生畸变
根据图像细化后的特性,并非所有形状的图像都适合进行细化,其主要应用在由线条形状组成的物体,例如圆环、文字等
但是实心圆不适合进行细化
根据算法处理步骤不同,细化算法又分为迭代细化算法和非迭代细化算法
根据检测像素方法的不同,迭代细化算法又分为串行细化算法和并行细化算法
OpenCV4提供了用于将二值图像细化的thinning()函数
thinning()函数原型:
void cv::ximgprc::thinning(InputArray src,
OutputArray dst,
int thinningType = THINNING_ZHANGSUEN
)
- src:输入图像,必须是CV_8U的单通道图像
- dst:输出图像,与输入图像具有相同的尺寸和数据类型
- thinningType:细化算法标志,可以选择参数为THINNING_ZHANGSUEN(简记为0)和THINNING_GUOHALL(简记为1)
该函数可以对图像的连通域进行细化,得到单位像素宽度的连通域
第一个参数是输入图像,要求必须是CV_8U的单通道图像
第二个参数是输出图像,与输入图像具有相同的尺寸和数据类型
第三个参数为细化算法标志,一种是在并行细化算法中常用的Zhang算法可以用THINNING_ZHANGSUEN(简记为0)表示
另一种是Guo细化方法,可以用THINNING_GUOHALL(简记为1)表示
示例:
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/ximgproc.hpp> //细化函数thinning()所在头文件
using namespace std;
using namespace cv;
int main()
{
//对字符进行细化
Mat img = imread("E:\\CLion\\opencv_xin\\SG\\SG_black.png",IMREAD_ANYDEPTH); //以8位读取
if (img.empty())
{
cout << "error" << endl;
return -1;
}
//对字符、实心圆和圆环进行细化
Mat words = Mat::zeros(100,200,CV_8UC1); //创建一个黑色的背景图片
putText(words,"Learn",Point(30,30),2,1, Scalar(255),2); //添加字符
putText(words,"OpenCV 4",Point(30,60),2,1, Scalar(255),2); //添加字符
circle(words,Point(80,75),10,Scalar(255),-1); //添加实心圆
circle(words,Point(130,75),10,Scalar(255),3); //添加圆环
//进行细化
Mat thin1,thin2;
ximgproc::thinning(img,thin1,0); //注意类名
ximgproc::thinning(words,thin2,0); //注意类名
//显示处理结果
imshow("thin1",thin1);
imshow("img",img);
namedWindow("thin2",WINDOW_GUI_NORMAL);
imshow("thin2",thin2);
namedWindow("words",WINDOW_GUI_NORMAL);
imshow("words",words);
waitKey(0);
return 0;
}