opencv-python 小白笔记(10)

(一)harris角点检测(cv2.cornerHarris)

角点检测这里使用的是cv2.cornerHarris(),主要参数有下面四个:
img: 数据类型为 float32 的入图像
blockSize: 角点检测中指定区域的大小
ksize: Sobel求导中使用的窗口大小
k: 取值参数为 [0,04,0.06]
其中最后一个K,我个人感觉不是只能取那三个值,我最高取到了0.1,还是检测到了角点,只是效果不太好,小伙伴们可以多试试改一下上面的几个参数

import cv2
import numpy as np

img=cv2.imread("1.png")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)


dst = cv2.cornerHarris(gray, 2, 3, 0.04)
dst = cv2.dilate(dst,None)#可有可无,可以增加角点的大小
img[dst>0.1*dst.max()]=[0,255,0]#角点为原谅色
cv2.imshow('dst ',img)
cv2.waitKey(0)

其中上面的img[dst>0.1*dst.max()]=[0,255,0]这里是设定一个阈值 当大于这个阈值分数的都可以判定为角点(然后角点为原谅色),其中前面的系数0.1小伙伴们可以多改改,一般是系数越小,角点越多(且系数一般设置为0.01)
在这里插入图片描述

(二)运动物体的检测

这里使用混合高斯模型,在进行前景检测前,先对背景进行训练,对图像中每个背景采用一个混合高斯模型进行模拟,每个背景的混合高斯的个数可以自适应。然后在测试阶段,对新来的像素进行GMM匹配,如果该像素值能够匹配其中一个高斯,则认为是背景,否则认为是前景。由于整个过程GMM模型在不断更新学习中,所以对动态背景有一定的鲁棒性。

下面我们识别视频中的人
原理就不讲了,上代码:

import numpy as np
import cv2

#经典的测试视频
cap = cv2.VideoCapture('test.avi')
#形态学操作需要使用
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3))
#创建混合高斯模型用于背景建模
fgbg = cv2.createBackgroundSubtractorMOG2()

while(True):
    ret, frame = cap.read()
    mask = fgbg.apply(frame)
    #形态学开运算去噪点
    mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)
    #寻找视频中的轮廓
    contours, hierarchy = cv2.findContours(mask, cv2.RETR_EXTERNAL,
                                           cv2.CHAIN_APPROX_SIMPLE)

    for c in contours:
        #计算各轮廓的周长
        peri = cv2.arcLength(c,True)
        if peri > 175:#这里对轮廓进行过滤(因为视频中的警戒线也在飘动),正因为这个过滤,导致左上角的一个人没有框选出来
            #找到一个直矩形(不会旋转)
            x,y,w,h = cv2.boundingRect(c)
            #画出这个矩形
            cv2.rectangle(frame,(x,y),(x+w,y+h),(0,255,0),2)#原谅色
            cv2.putText(frame,"people",(x-10,y-10),
                        cv2.FONT_HERSHEY_COMPLEX, 0.7,
                        (0, 255, 0),3)#原谅色

    cv2.imshow('frame',frame)
    cv2.imshow('mask', mask)
    k = cv2.waitKey(100) & 0xff
    if k == 27:
        break

cap.release()
cv2.destroyAllWindows()

这里其实还有一种方法叫(帧差法)背景减法,但我个人感觉不怎么好用,所以就不介绍了

运行结果

(三)点与轮廓的关系(cv2.pointPolygonTest)

使用该函数可以确定一个点与轮廓的距离和位置关系
该函数有三个参数,第一个是目标轮廓,第二个是目标点的,第三个参数是measureDist。如果设置为True,就会计算最短距离。如果是False,只会判断这个点与轮廓之间的位置关系(返回值为+1,-1,0)

这里我们选择3个点分别计算它们与图中椭圆的位置关系和距离,三个点分别为(365,34)(365,68)(365,129)

import cv2
import numpy as np

img = cv2.imread('1.png')

imgGray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#转为灰度图
imgBlur = cv2.GaussianBlur(imgGray,(7,7),1)#高斯降噪
imgCanny = cv2.Canny(imgBlur,50,50)#canny边缘检测
contours,hierarchy = cv2.findContours(imgCanny,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)#提取图像外轮廓,并返回至contours

img_output=cv2.drawContours(img.copy(), contours, 3, (0, 255, 0), 3)#这里使用原谅色
#这里有一个细节,那就是我们并没有直接在原图上画出轮廓,因为在原图上,会直接破会原图信息,这里3为椭圆的轮廓
test1=cv2.pointPolygonTest(contours[3],(365,34),True)
test2=cv2.pointPolygonTest(contours[3],(365,63),True)
test3=cv2.pointPolygonTest(contours[3],(365,129),True)
test4=cv2.pointPolygonTest(contours[3],(365,34),False)
test5=cv2.pointPolygonTest(contours[3],(365,63),False)
test6=cv2.pointPolygonTest(contours[3],(365,129),False)

print("test1=",test1)
print("test2=",test2)
print("test3=",test3)
print("test1的位置为",test4)
print("test2的位置为",test5)
print("test3的位置为",test6)

cv2.imshow("img_output", img_output)

cv2.waitKey(0)

在这里插入图片描述
终端的打印的信息为:
test1= -29.0
test2= -0.0
test3= 54.0
test1的位置为 -1.0(轮廓的外围)
test2的位置为 0.0(在轮廓的上面)
test3的位置为 1.0(轮廓的内部)

(四)结语

学习opencv有很多的方法,我的建议是你可以加一些群,可以充分利用B站,CSDN,和百度。

在我的博客中,我不会讲解opencv的算法实现(当然我也不太会),我只会讲解一些函数的调用,不理解就多改一些参数,多尝试尝试,慢慢你就理解来。相信你总有一天可以说opencv不过“Ctrl+C,Crtl+V”

如果有什么错误的地方,还请大家批评指正,最后,希望小伙伴们都能有所收获。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值