目录
1、RGB转HSV
2、inRange颜色过滤
3、模糊处理
4、图像二值化
5、获取结构化元素(核)
6、形态学操作函数morphologyEx
关于RGB与HSV的区别不做过多赘述,在OpenCV处理图像,检测颜色信息时往往用HSV空间而不用RGB空间,个人粗略的理解是HSV对颜色的刻画更细致真实,在处理过程中设置各种阙值更方便。
转换方法:OpenCV自带函数:CV_EXPORTS_W void cvtColor( InputArray src, OutputArray dst, int code, int dstCn = 0 );
InputArray src: 输入图像
OutputArray dst: 输出图像
int code 为颜色转换空间标志符,取值见 https://blog.csdn.net/hjxu2016/article/details/81117917
int dstCn = 0: 目标图像的通道数,如果该参数为0,通道数取原图像的通道数
int main()
{
Mat hsvimage1 = imread("C:\\Users\\dell\\Desktop\\毕业设计\\a.jpg");
Mat hsvimage;
cvtColor(hsvimage1,hsvimage,CV_BGR2HSV); //显示图像
//= cvarrToMat(image1);
namedWindow("HSV", 0); //HSV
imshow("HSV", hsvimage1);
namedWindow("fenge", 0); //HSV
imshow("fenge", hsvimage);
}
把图像转换为HSV后可以设置阙值提取响应颜色的区域 。
OpenCV提供了inRange函数,两个阙值间的像素值设为白色,其余的设为黑色,且多通道。
inRange的定义: void inRange (InputArray src, InputArray lowerb, InputArray upperb, OutputArray dst);
src:要处理的图片
lowerb:包含下边界的数组或标量。(下阙值)
upperb:包含上边界数组或标量。 (上阙值)
dst:输出图像
以下为提取蓝色区域:
Mat fenge;
//inRange函数,两个阙值间的像素值设为白色,其余的设为黑色,且多通道
inRange(hsvimage,Scalar(100, 50, 50), Scalar(124, 255, 255),fenge);
结果:
在上一个inRange处理后,可以注意到处理后的图片左边由于干扰提取出白点,通过模糊处理去掉:
OpenCV提供的函数: void blur(InputArray src, OutputArray dst, Size ksize, Point anchor=Point(-1,-1), int borderType=BORDER_DEFAULT )
src:源图像
dst:目标图像
ksize:Size类型,一般这样写Size( w,h )来表示内核的大小( 其中,w 为像素宽度, h为像素高度)。Size(3,3)就表示3x3的核大小,Size(5,5)就表示5x5的核大小。浅显说明一下,w,h的数值越大,越模糊。关于内核的理解就像一个矩阵,如果你定义的w,h越小,矩阵越小,在此矩阵从图像上滑动运算的时候,计算越细致,所以越不模糊、、、、
anchor:Point点类,表示锚点(即被平滑的那个点),有默认值Point(-1,-1)。如果这个点坐标是负值的话,就表示取核的中心为锚点,所以默认值Point(-1,-1)表示这个锚点在核的中心。
borderType:int类型的borderType,用于推断图像外部像素的某种边界模式。有默认值BORDER_DEFAULT,一般不去管它。
Mat blurr;
blur(fenge, blurr, Size(9, 9));
效果:
模糊处理后的图像要重新二值化(黑白二值)
OpenCV函数:threshold (通过遍历灰度图中点,将图像信息二值化,处理过后的图片只有二种色值)
原型:double threshold(InputArray src, OutputArray dst, double thresh, double maxval, int type)
src:源图新
dst:目标图像
thresh:阈值的具体值
maxval:当第五个参数阈值类型type取 THRESH_BINARY 或THRESH_BINARY_INV阈值类型时的最大值.
type:int类型,表示阙值类型:
0: THRESH_BINARY 当前点值大于时,取Maxval,也就是第四个参数,下面再不说明,否则设置为0
1: THRESH_BINARY_INV 当前点值大于阈值时,设置为0,否则设置为Maxval
2: THRESH_TRUNC 当前点值大于阈值时,设置为阈值,否则不改变
3: THRESH_TOZERO 当前点值大于阈值时,不改变,否则设置为0
4: THRESH_TOZERO_INV 当前点值大于阈值时,设置为0,否则不改变
Mat new_blurr;
threshold(blurr,new_blurr, 100, 255, THRESH_BINARY);
效果:
OpenCV的 getStructuringElement 函数会返回指定形状和尺寸的结构元素。
原型:Mat getStructuringElement(int shape, Size esize, Point anchor = Point(-1, -1));
shape:表示内核的形状,有三种形状可以选择。矩形:MORPH_RECT,,交叉形:MORPH_CROSS;
椭圆形:MORPH_ELLIPSE;
esize:想要的核的大小
anchor:锚点,默认(-1,-1)在中心
这个函数,说白了就是帮助我们生成一个核,而不用自己定义内核数组填值,shape就是内核的形状,Size就是内核的大小,写Size(m,n),相当于一个m*n的矩阵。
Mat kernel = getStructuringElement(MORPH_RECT,Size(21,7));
函数原型:
void morphologyEx( InputArray src, OutputArray dst,
int op, InputArray kernel,
Point anchor = Point(-1,-1), int iterations = 1,
int borderType = BORDER_CONSTANT,
const Scalar& borderValue = morphologyDefaultBorderValue() )
src,dst分别是源图新,目标图像
op:操作的类型,有:
MORPH_ERODE = 0, //腐蚀
MORPH_DILATE = 1, //膨胀
MORPH_OPEN = 2, //开操作
MORPH_CLOSE = 3, //闭操作
MORPH_GRADIENT = 4, //梯度操作
MORPH_TOPHAT = 5, //顶帽操作
MORPH_BLACKHAT = 6, //黑帽操作
MORPH_HITMISS = 7
kernel:核元素,用于膨胀操作的结构元素,如果取值为Mat(),那么默认使用一个3 x 3 的方形结构元素,可以使用getStructuringElement()来创建结构元素。
anchor:参考点,其默认值为(-1,-1)说明位于kernel的中心位置。
borderType :边缘类型,默认为BORDER_CONSTANT。
borderValue :边缘值,用它的默认值即可。
这里实现一个闭操作:
Mat closed;
//kernel是上一步生成的核,new_blurr是之前二值化后的结果
morphologyEx(new_blurr, closed, MORPH_CLOSE, kernel);
效果: