OpenCV学习笔记(二)采用OpenCV-python对采集到的图像采用四种滤波方式进行边缘检测,并采用多线程

2021/7/8 1:07:21

本文主要是介绍OpenCV学习笔记(二)采用OpenCV-python对采集到的图像采用四种滤波方式进行边缘检测,并采用多线程,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

博主学习python做的第二个小项目,blog用以记录学习过程

任务要求:

1、调取NVIDIA NX系统摄像头,获取视频(帧)流
2、四种滤波分别采用:Canny、Sobel、Laplacian、Scharr
3、多进程(threading)

一、调取摄像头获取视频帧

详见上一篇blog:blog链接

二、四种滤波

  • Sobel滤波和Scharr滤波

    两种滤波器本质上是同一种,Scharr滤波器是Sobel滤波器的特殊情况,具体描述见下图滤波原理
    代码如下:

	#sobel滤波
    sobelx = cv2.Sobel(gray, cv2.CV_64F, 1, 0)
    sobely = cv2.Sobel(gray, cv2.CV_64F, 0, 1)
    #在进行滤波时需要将数据类型从uint8转换为更高的CV_64F,内核矩阵即ksize默认为3
    sobelx = numpy.uint8(numpy.absolute(sobelx))
    sobely = numpy.uint8(numpy.absolute(sobely))
    #滤波完成后需要将图片转换为能够哦显示的uint8
    sobelcombine = cv2.bitwise_or(sobelx,sobely)
    #对两幅分别在x和y方向进行求导的图片数据进行或操作叠加
	#scharr滤波
    scharr_x = cv2.Sobel(gray,cv2.CV_64F, 1, 0, ksize = -1)
    scharr_y = cv2.Sobel(gray,cv2.CV_64F, 0, 1, ksize = -1)
    #可以看到另sobel函数中的ksize = -1便可以为scharr函数
    scharrcombine = cv2.addWeighted(scharr_x, 0.5, scharr_y, 0.5, 0)
    #这里采用addWeight()函数进行
    #scharrcombine = cv2.bitwise_or(scharr_x,scharr_y)
    scharrcombine = cv2.convertScaleAbs(scharrcombine)
    #这里采用convertScaleAbs()函数对叠加后的图片进行强制类型转换,以便后续采用imshow函数进行显示
  • Laplacian滤波
    在这里插入图片描述
    lapci = cv2.Laplacian(gray,cv2.CV_64F,ksize=3)
    lapci = cv2.convertScaleAbs(lapci)

Laplacian,Sobel对同一张图片进行的滤波效果如下图:
在这里插入图片描述

  • Canny滤波

    核心为两个阈值:
    在这里插入图片描述

    代码:

	#Canny滤波
	canny = cv2.Canny(gray,50,100)
	#gray为灰度化后的图像

三、多线程处理

推荐b站莫烦的python多线程教程,链接:莫烦python,Threading学会多线程
另外这位博主对莫烦的内容进行了一定的整理,参见:多线程blog链接

小项目所有代码如下:

import threading
import cv2
import numpy
from queue import Queue

def T1_job(gary,q):
    print("T1 start")
    canny = cv2.Canny(gray,50,100)
    print("T1 finish")
    q.put(canny)
def T2_job(gray,q):
    print("T2 start")
    sobelx = cv2.Sobel(gray, cv2.CV_64F, 1, 0)
    sobely = cv2.Sobel(gray, cv2.CV_64F, 0, 1)
    
    sobelx = numpy.uint8(numpy.absolute(sobelx))
    sobely = numpy.uint8(numpy.absolute(sobely))
    sobelcombine = cv2.bitwise_or(sobelx,sobely)
    #gray = sobekcombine
    print("T2 finish")
    q.put(sobelcombine)
def T3_job(gray,q):
    print("T3 start")
    scharr_x = cv2.Sobel(gray,cv2.CV_64F, 1, 0, ksize = -1)
    scharr_y = cv2.Sobel(gray,cv2.CV_64F, 0, 1, ksize = -1)
    scharrcombine = cv2.addWeighted(scharr_x, 0.5, scharr_y, 0.5, 0)
    #scharrcombine = cv2.bitwise_or(scharr_x,scharr_y)
    scharrcombine = cv2.convertScaleAbs(scharrcombine)
    print("T3 finish")
    q.put(scharrcombine)
def T4_job(gray,q):
    print("T4 start")
    lapci = cv2.Laplacian(gray,cv2.CV_64F,ksize=3)
    lapci = cv2.convertScaleAbs(lapci)
   # gray = lapci
    print("T4 finish")
    q.put(lapci)
 cap = cv2.VideoCapture(0)

while(1):
    # get a frame
    ret, frame = cap.read()
	#ret表示返回的布尔值,frame是返回的图像帧,read表示读取帧
    # show a frame
	# cv2.namedWindow("cpature",cv2.WINDOW_NORMAL)

    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    
    q =Queue() #  #q中存放返回值,代替return的返回值
    threads = []
    thread_1 = threading.Thread(target = T1_job,args=(gray,q))
    thread_2 = threading.Thread(target = T2_job,args=(gray,q))
    thread_3 = threading.Thread(target = T3_job,args=(gray,q))
    thread_4 = threading.Thread(target = T4_job,args=(gray,q))

    threads.append(thread_1)
    threads.append(thread_2)
    threads.append(thread_3)
    threads.append(thread_4)

    for thread in threads:
        thread.start()
    for thread in threads:
        thread.join()
    results = []
    for _ in range(4):
        results.append(q.get())#q.get()按顺序从q中拿出一个值
    
    cv2.imshow("capture0",results[0])
    cv2.imshow("capture1",results[1])
    cv2.imshow("capture2",results[2])
    cv2.imshow("capture3",results[3])
    
    if cv2.waitKey(1) & 0xFF == ord('q'):
    #waitKey("时间")表示延迟多少ms
    #这里&为与运算符号,一般都用$$,效率更高
        break
#循环只有在对程序框按下q并且延时1ms后才会中断

cap.release()
cv2.destroyAllWindows() 
#最后关闭窗口是一个好习惯

这篇blog写的比较仓促,后续会更新更多细节以及优化代码,代码仅仅达到了能跑结果正确的程度,还需要进行优化,仅供参考。

本文截图的内容来自书籍:《OpenCV-Python-Tutorial-中文版》,可入qq群783462347文件区下载以及python的学习交流,一个兴趣使然的群,均为免费~



这篇关于OpenCV学习笔记(二)采用OpenCV-python对采集到的图像采用四种滤波方式进行边缘检测,并采用多线程的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程