python openCv 入门学习-移动物体捕获(六)

概念

图像二值化
  • 二值化( Image Binarization)就是将图像上的像素点的灰度值设置为0或
    255,也就是将整个图像呈现出明显的黑白效果的过程。
  • 在数字图像处理中,二值图像占有非常重要的地位,图像的二值化使图像中数据量大为减少,从而能凸显出目标的轮廓。
形态学操作
  • 腐蚀与膨胀属于形态学操作,所谓的形态学,就是改变物体的形状,形象理解一些:腐蚀=变瘦 膨胀=变胖 ,主要是采用 变瘦cv2.erode() 和 变胖cv2.dilate()

  • 腐蚀和膨胀主要针对二值化图像的白色部分

  • 膨胀与腐蚀能够实现以下作用:

    1.消除噪声

    2.分割出独立的图像元素,在图像中连接相邻的元素

    3.寻找图像中的明显的极大值区域或者极小值区域

    4.求出图像的梯度

相关运算
 开运算,闭运算,顶帽,顶帽
  • 开运算:先进行腐蚀操作,后进行膨胀操作,主要用来去除一些较亮的部分,即先腐蚀掉不要的部分,再进行膨胀。
  • 闭运算:先进行膨胀操作,后进行腐蚀操作,主要用来去除一些较暗的部分。
  • 形态学梯度:膨胀运算结果减去腐蚀运算结果,可以拿到轮廓信息。
  • 顶帽运算:原图像减去开运算结果。
  • 底帽运算:原图像减去闭运算结果。

进行开运算,闭运算,顶帽运算,底帽运算,形态学梯度,opencv提供了一个统一的函数cv2.morphologyEx(),其对应参数如下:

dst = cv2.morphologyEx(src,op,kernel,anchor,iterations,borderType,borderValue)
        src: 输入图像对象矩阵,为二值化图像
        op: 形态学操作类型
            cv2.MORPH_OPEN    开运算
            cv2.MORPH_CLOSE   闭运算
            cv2.MORPH_GRADIENT 形态梯度
            cv2.MORPH_TOPHAT   顶帽运算
            cv2.MORPH_BLACKHAT  底帽运算
            
        kernel:进行腐蚀操作的核,可以通过函数getStructuringElement()获得
        anchor:锚点,默认为(-1,-1)
        iterations:腐蚀操作的次数,默认为1
        borderType: 边界种类
        borderValue:边界值

原理

  1. 开启摄像头读取图片
  2. 通过KNN背景分割器剔除背景,获得移动物体遮罩
  3. 将遮罩二值化处理
  4. 将遮罩开运算
  5. 得到面积大于3000的遮罩轮廓(四个点)
  6. 在原图上画矩形

代码解释

import cv2
import numpy as np
//背景分割器
bs=cv2.createBackgroundSubtractorKNN(detectShadows=True)
camera=cv2.VideoCapture(0)
camera.set(3,320)
camera.set(4,160)

while True:
	//frame的类型为numpy
    ret,frame=camera.read()
    //背景分割器,该函数计算了前景掩码
    //apply()返回的是高X宽的一个numpy矩阵,这里是160x320,如果没有移动物体那么这个矩阵全部为0
    fgmask=bs.apply(frame)
	/**
		threshold作用
			二值化阈值处理,前景掩码含有前景的白色值以及阴影的灰色值,在阈值化图像
			中,将非纯白色(244~255)的所有像素都设为0,而不是255
		图像二值化
			src:表示的是图片源
		 	thresh:表示的是阈值(起始值)
		 	maxval:表示的是最大值
		 	type:表示的是这里划分的时候使用的是什么类型的算法
			 	1.cv2.THRESH_BINARY   表示阈值的二值化操作,大于阈值使用maxval表示,小于阈值使用0表示
	    		2. cv2.THRESH_BINARY_INV  表示阈值的二值化翻转操作,大于阈值的使用0表示,小于阈值的使用最大值表示
	    		3. cv2.THRESH_TRUNC    表示进行截断操作,大于阈值的使用阈值表示,小于阈值的不变
	    		4. cv2.THRESH_TOZERO   表示进行化零操作,大于阈值的不变,小于阈值的使用0表示
	    		5. cv2.THRESH_TOZERO_INV  表示进行化零操作的翻转,大于阈值的使用0表示,小于阈值的不变
	    返回值:
		    ret:True或False,代表有没有读到图片;
			dst: 目标图像;
	*/
    th=cv2.threshold(fgmask.copy(),244,255,cv2.THRESH_BINARY)[1]
    /**
     	src: 输入图像对象矩阵,为二值化图像
        kernel:进行腐蚀操作的核,可以通过函数getStructuringElement()获得
        anchor:锚点,默认为(-1,-1)
        iterations:腐蚀操作的次数,默认为1
        borderType: 边界种类,有默认值
        borderValue:边界值,有默认值
			cv2.getStructuringElement()
					shape:核的形状
		                cv2.MORPH_RECT: 矩形
		                cv2.MORPH_CROSS: 十字形(以矩形的锚点为中心的十字架)
		                cv2.MORPH_ELLIPSE:椭圆(矩形的内切椭圆)    
	       			ksize: 核的大小,矩形的宽,高格式为(width,height)
	        		anchor: 核的锚点,默认值为(-1,-1),即核的中心点
	*/
    th=cv2.erode(th,cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3)),iterations=2)
    //开运算
    dilated=cv2.dilate(th,cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3)),iterations=2)
    //获取轮廓 (第三讲研究过了) cv2.RETR_EXTERNAL只检测外轮廓
    //cv2.CHAIN_APPROX_SIMPLE压缩水平方向、垂直方向、对角线方向的元素,只保留该方向的终点坐标,例如一个矩形轮廓只需要4个点来保存轮廓信息;
	image,contours,hier=cv2.findContours(dilated,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
    
    for c in contours:
    	//轮廓面积>3000
        if cv2.contourArea(c)>3000:
        	/**
				cv2.boundingRect(img)这个函数
				这个函数很简单,img是一个二值图,也就是它的参数;返回四个值,分别是
				x,y,w,h;x,y是矩阵左上点的坐标,w,h是矩阵的宽和高。
				然后利用cv2.rectangle(img, (x,y), (x+w,y+h), (0,255,0), 2)画出
				矩行
				参数解释
					第一个参数:img是原图
					第二个参数:(x,y)是矩阵的左上点坐标
					第三个参数:(x+w,y+h)是矩阵的右下点坐标
					第四个参数:(0,255,0)是画线对应的rgb颜色
					第五个参数:2是所画的线的宽度
			*/
            (x,y,w,h)=cv2.boundingRect(c)
            cv2.rectangle(frame,(x,y),(x+w,y+h),(255,255,0),2)
        if x!=0 and y!=0:
            print('x',x,'y',y)
    cv2.imshow("mog",fgmask)
    cv2.imshow("detection",frame)
    if (cv2.waitKey(30)&0xFF)==27:
        break
    if (cv2.waitKey(30)&0xFF)==ord('q'):
        break
camera.release()
cv2.destroyAllWindows()
参考自大佬:(silence_cho )https://www.cnblogs.com/silence-cho/p/11069903.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值