open cv提取水平线与垂直线
形态学操作提取水平线与垂直线的原理方法
图像形态学操作时候,可以通过自定义的结构元素实现结构元素
对输入图像-些对象敏感另外一些对象不敏感,这样就会让敏
感的对象改变而不敏感的对象保留输出。通过使用两个最基本的
形态学操作-膨胀与腐蚀,使用不同的结构元素实现对输入图像
的操作、得到想要的结果
.膨胀,输出的像素值是结构元素覆盖下输入图像的最大像素值
.腐蚀,输出的像素值是结构元素覆盖下输入图像的最小像素值
举例说明:例如想检测水平线,可以构造一个类型为
MORPH_RECT尺寸为Size(src.cols / 16, 1)
(一个水平细长条矩形模板)的结构元素,
这样经过腐蚀操作,垂直线(二值图像中)
会对其敏感从而消除,水平线受其影响较小,
经过膨胀操作,最终还原图像中的水平线。
结构元素
●上述膨胀与腐蚀过程可以使用任意的结构元素
●常见的形状:矩形、圆、直线、磁盘形状、砖石形状
等各种自定义形状
提取步骤
1.输入彩色图像imread
2.转换为灰度图像cvtCOLOR
3.转换为二值图像adaptiveThreshold
4.定义结构元素getStructuringElement
5.开操作(腐蚀+膨胀)提取水平与垂直线
cv::morphologyEx() 形态学操作函数
void cv::adaptiveThreshold(
cv::InputArray src, // 输入图像
double maxValue, // 向上最大值 255
int adaptiveMethod, // 自适应方法,平均或高斯 mean&gussian
int thresholdType // 阈值化类型 THRESH_BINARY
int blockSize, // 块大小
double C // 常量 可以为负数
基本流程
1.首先要确保图片为灰度单通道的图片方便二值化的处理 cvtcolor
2.按照图片的亮度均匀程度进行分类二值化(亮度差大的采取自适应阀门二值化(需要取反导入图片),差不大的使用全局阀门二值化)
所使用API adaptiveThreshold&threshold
3.获取合适的结构元素为接下来的形态学开操作做准备(水平线与垂直线各自需要一个结构元素)
所使用API getStructuringElement
4.对设置好结构元素图片进行开操作(先膨胀后腐蚀)
5.混合图片并进行模糊化处理 增强视觉效果
6.有需求时对图片进行去取反操作(目的是与原图保持一致)
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui_c.h>
#include <iostream>
using namespace cv;
using namespace std;
Mat dst,src,HLINE,VLINE,MIX,ABC;
int Osize = 3;
int Oosize = 3;
int Msize = 21;
int Tsize=1;
float alpha = 0.5;
void HlineVline(int, void*);
int main()
{
src = imread("D:/实验台/机器视觉/测试图片/二值化操作.jpg",IMREAD_GRAYSCALE);//灰度加载
if (!src.data)
{
cout << "无法导入" << endl;
return -1;
}
imshow("原图",src);
namedWindow("水平线",CV_WINDOW_AUTOSIZE);
createTrackbar("结构元素", "水平线", &Osize, Msize, HlineVline);
createTrackbar("二值化参数", "水平线", &Oosize, Msize, HlineVline);
HlineVline(0,0);
waitKey(0);
}
//灰色衬衫的轮廓显示及其调节
//二值化-梯度操作获取-混合原图-实现
void OutLineofGrayShirt(int, void*)
{
Tsize = 210;
int s = Oosize * 2 + 1;
threshold(src, dst, Tsize, 255, THRESH_BINARY);
Mat SE = getStructuringElement(MORPH_RECT,Size(s,s),Point(-1,-1));
morphologyEx(dst,dst,CV_MOP_GRADIENT,SE);
addWeighted(dst,alpha,src,(1-alpha),0.0,dst1);
//adaptiveThreshold(src, dst, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, Tsize, -2);
imshow("原图",dst);
imshow("结果",dst1);
return;
}
//提取水平线与水直线
void HlineVline(int, void*)
{
Tsize = Osize * 32;//全局阀值化调节&形态学结构元素体调节
//threshold(src, dst, Tsize, 255, THRESH_BINARY);
///全局阀值化 只能全局调节
int s = Oosize * 2 + 1;
//自适应阀值化卷积核调节
adaptiveThreshold(~src, dst, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, s, -2);
//自适应阀值化(输入图片,输出图片,二值化最大值,自适应算法,阀值类型,邻域块大小,权重);
//自适应阀值化 ~src灰度图取反,会让灰度图中的黑色线条像素值较高大于阈值,二值化后变成明显的白条。
//适用于亮度不均衡的图片 按照领域块大小s 及 权重-2进行局部调节
Mat hline = getStructuringElement(MORPH_RECT, Size(src.cols / Tsize, 1), Point(-1, -1));
//水平结构元素 获得一个水平的结构元素(长条状结构元素进行膨胀覆盖了竖线条),Size(列,行);
Mat vline = getStructuringElement(MORPH_RECT,Size(1,src.rows/Tsize), Point(-1, -1));//水平线
//垂直结构元素 获得一个垂直的结构元素
//Mat temp;//先膨胀再腐蚀
//erode(dst,temp,vline);膨胀操作
//dilate(temp, dst, vline);腐蚀操作
//这两个基本操作 等效于形态学操作的开操作
morphologyEx(dst, HLINE, CV_MOP_OPEN, hline);
morphologyEx(dst, VLINE, CV_MOP_OPEN, vline);
//膨胀(用设定的长条状结构元素进行膨胀此时水平线受影响最小)后腐蚀(让受影响的水平线进行腐蚀恢复水平线宽度) 获取横(竖)线条,用hline(vline)结构元素进行开操作
//bitwise_not(HLINE,HLINE);//二值化反差 黑变白 变回原图配色
//bitwise_not(VLINE, VLINE);//二值化反差 直接在图片前面取反也可以实现
imshow("水平线",~HLINE);
imshow("垂直线",~VLINE);
addWeighted(HLINE, alpha, VLINE, (1 - alpha), 0.0, MIX);//水平线水直线混合显示 复原原图
blur(MIX, MIX, Size(3,3),Point(-1,-1));//模糊图像进行边缘柔化美化图像
imshow("混合",MIX);
imshow("二值化",dst);
return;
}
去掉干扰线显示字母
void CleanABC(int, void*)
{
int s = Oosize * 2 + 1;//形态操作卷积核调节
adaptiveThreshold(~src, dst, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 15, -2);//自适应阀门;
Mat kernel = getStructuringElement(MORPH_RECT, Size(s, s), Point(-1, -1));
morphologyEx(dst, ABC, CV_MOP_OPEN, kernel);
//形态学操作在使用前必须确保预处理图像为二值化图像 否则会报错
imshow("字母去干扰线", ABC);//用于去掉OCR识别的干扰线
return;
}
在图像阈值化操作中,更关注的是从二值化图像中,
分离目标区域和背景区域,但是仅仅通过设定固定阈值很难达到理想的分割效果
它的思想不是计算全局图像的阈值,而是根据图像不同区域亮度分布,
计算其局部阈值,所以对于图像不同区域,能够自适应计算不同的阈值
因此被称为自适应阈值法。(其实就是局部阈值法)对光照不均匀的图像尤其适用。
adaptiveThreshold(~src, dst, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY,s, -2);
第一个参数:输入的灰度图像
第二个参数:传出的二值图像
第三个参数:二值图像最大值
第四个参数:指定自适应阈值算法。可选择ADAPTIVE_THRESH_MEAN_C 或 ADAPTIVE_THRESH_GAUSSIAN_C其中一种。
第五个参数:指定阈值类型。可选择THRESH_BINARY或者THRESH_BINARY_INV其中一种。(即二进制阈值或反二进制阈值)。
第六个参数:表示邻域块大小,用来计算区域阈值,一般选择为3、5、7…等。
第七个参数:参数C表示与算法有关的参数,它是一个从均值或加权均值提取的常数,可以是负数。
基于自适应阈值二值化API adaptiveThreshold的直线提取效果
cv::adaptiveThreshold()支持两种自适应方法
即cv::ADAPTIVE_THRESH_MEAN_C(平均)
和cv::ADAPTIVE_THRESH_GAUSSIAN_C(高斯)
在两种情况下,自适应阈值T(x, y)。
通过计算每个像素周围bxb大小像素块的加权均值并减去常量C得到
其中,b由blockSize给出,大小必须为奇数;如果使用平均的方法,
则所有像素周围的权值相同;如果使用高斯的方法,则(x,y)
周围的像素的权值则根据其到中心点的距离通过高斯方程得到
二值化阈值类型