手把手带你入坑树莓派(3B+)之第四篇,安装OpenCV+一个成功案例

我想做树莓派手指识别,想用QT+OpenCV库编写代码。就涉及到了要安装opencv。我肯定成功了。我相信你也可以,只要跟着我一起做。

第一步,安装OpenCV

在下图所示的路径下:

把以下代码挨个从上到下给安装了。

sudo apt-get update   #更新源
sudo apt-get upgrade   #更新已安装程序!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!  
#以下是更新依赖
sudo apt-get install build-essential cmake pkg-config
sudo apt-get install libjpeg-dev libtiff5-dev libjasper-dev libpng12-dev
sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev
sudo apt-get install libxvidcore-dev libx264-dev
sudo apt-get install libgtk2.0-dev libgtk-3-dev
sudo apt-get install libatlas-base-dev gfortran
#以下是更新Python3和PIP3
sudo apt-get install python3-dev
sudo apt-get install python3-pip
#以下是安装OpenCV
pip3 install opencv-python
#以下是摄像头依赖
sudo apt-get install libqtgui4
sudo apt-get install libqt4-test

然后你需要输入:

sudo raspi-config

找到5.Interfacing Options 找到P1 Camera把它使能(Enable)。

sudo modprobe bcm2835-v4l2

然后在cd home/pi目录下创建一个叫opencv_text.py的文件,用来测试摄像头是否与OpenCV配好了。

sudo nano opencv_text.py        #创建个新python文件并用nano编辑

把以下代码粘贴到打开的opencv_text.py文件中。

import cv2
import numpy as np

cap = cv2.VideoCapture(0)

while  True:
    _, frame = cap.read()
    
    cv2.imshow("Frame", frame)
    
    key = cv2.waitKey(1)
    if key == 27:
        break

cap.release()
cv2.destroyALLWindows()

 Ctrl+X退出,Y保存,Enter退出编辑界面。

然后用把它打开并Run

然后就可以了:

第二步,Try more examples

Number of fingers image detection

import numpy as np
import cv2
from threading import Event
import re
import math
import time
import random
import os
def _remove_background(img):#去除背景
    fgbg = cv2.createBackgroundSubtractorMOG2() # 利用BackgroundSubtractorMOG2算法消除背景
    fgmask = fgbg.apply(img)
    #cv2.imshow("image2", fgmask)
    kernel = np.ones((3, 3), np.uint8)
    fgmask = cv2.erode(fgmask, kernel, iterations=1)
    res = cv2.bitwise_and(img, img, mask=fgmask)
    return res

def _bodyskin_detetc(frame):#得到去除背景的图片skin
    # 肤色检测: YCrCb之Cr分量 + OTSU二值化
    ycrcb = cv2.cvtColor(frame, cv2.COLOR_BGR2YCrCb) # 分解为YUV图像,得到CR分量
    (_, cr, _) = cv2.split(ycrcb)
    cr1 = cv2.GaussianBlur(cr, (5, 5), 0) # 高斯滤波
    _, skin = cv2.threshold(cr1, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)  # OTSU图像二值化
    cv2.imshow("image1", skin)
    return skin

def _get_contours(array):#得到图片所有的坐标
    contours, hierarchy = cv2.findContours(array, cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
    return contours

def _get_eucledian_distance(beg, end):#计算两点之间的坐标
    i=str(beg).split(',')
    j=i[0].split('(')
    x1=int(j[1])
    k=i[1].split(')')
    y1=int(k[0])
    i=str(end).split(',')
    j=i[0].split('(')
    x2=int(j[1])
    k=i[1].split(')')
    y2=int(k[0])
    d=math.sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))
    return d
    
def _get_defects_count(array, contour, defects, verbose = False):
    ndefects = 0
    for i in range(defects.shape[0]):
        s,e,f,_= defects[i,0]
        beg= tuple(contour[s][0])
        end= tuple(contour[e][0])
        far= tuple(contour[f][0])
        a= _get_eucledian_distance(beg, end)
        b= _get_eucledian_distance(beg, far)
        c= _get_eucledian_distance(end, far)
        angle= math.acos((b ** 2 + c ** 2 - a ** 2) / (2 * b * c)) # * 57
        if angle <= math.pi/2 :#90:
            ndefects = ndefects + 1
            if verbose:
                cv2.circle(array, far, 3, _COLOR_RED, -1)
                cv2.imshow("image2", array)
        if verbose:
            cv2.line(array, beg, end, _COLOR_RED, 1)
            cv2.imshow("image2", array)
    return array, ndefects

def grdetect(array, verbose = False):
    copy = array.copy()
    array = _remove_background(array) # 移除背景, add by wnavy
    thresh = _bodyskin_detetc(array)
    contours = _get_contours(thresh.copy()) # 计算图像的轮廓
    largecont= max(contours, key = lambda contour: cv2.contourArea(contour))
    hull= cv2.convexHull(largecont, returnPoints = False) # 计算轮廓的凸点
    defects= cv2.convexityDefects(largecont, hull) # 计算轮廓的凹点
    if defects is not None:
        # 利用凹陷点坐标, 根据余弦定理计算图像中锐角个数
        copy, ndefects = _get_defects_count(copy, largecont, defects, verbose = verbose)
        # 根据锐角个数判断手势, 会有一定的误差
        if   ndefects == 0:
            print("1根或0根")
        elif ndefects == 1:
            print("2根")
        elif ndefects == 2:
            print("3根")
        elif ndefects == 3:
            print("4根")
        elif ndefects == 4:
            print("5根")

def judge():
    imname =  "wif.jpg"
    img = cv2.imread(imname, cv2.IMREAD_COLOR)
    grdetect(img, verbose = False)
    
def game():
    capture = cv2.VideoCapture(0)#打开笔记本的内置摄像头
    cv2.namedWindow("camera",1)
    start_time = time.time()
    print("给你10秒的时间把手放到方框的位置\n")
    while(1):
        ha,img =capture.read()
        #按帧读取视频,ha,img为获取该方法的两个返回值,ha为布尔值,如果读取帧是正确的则返回true
        #如果文件读取到结尾,它的返回值就为false,img就是每一帧的图像,是个三维矩阵
        end_time = time.time()#返回当前时间的时间戳
        cv2.rectangle(img,(426,0),(640,250),(170,170,0))
        #cv2.putText(img,str(int((10-(end_time- start_time)))), (100,100), cv2.FONT_HERSHEY_SIMPLEX, 2, 255)
        #对应参数为图片、添加的文字,左上角图标,字体,字体大小,颜色,即上面一行功能为在图片中显示倒计时
        cv2.imshow("camera",img)
        if(end_time-start_time>10):#如果时间到达10秒
            break
        if(cv2.waitKey(30)>=0):
            break
        ha,img = capture.read()
        cv2.imshow("camera",img)
        img = img[0:210,426:640]
        cv2.imwrite("wif.jpg",img)
        judge()
    capture.release()
    
def main():
    while(1):
        os.system('cls')#清屏
        ans =game()
main()
 

Open a LED 

#LED
import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BOARD)
GPIO.setup(7,GPIO.OUT)
GPIO.output(7,GPIO.HIGH)


while True:
    GPIO.output(7,GPIO.LOW)
    time.sleep(1)

猜你喜欢

转载自blog.csdn.net/Smile_h_ahaha/article/details/108820523