树莓派基于opencv的颜色识别和二维码扫描

树莓派基于opencv的颜色识别和二维码扫描

本篇多数文字借鉴于博客园晓风小峰在实际操作的过程中做了自己的修改,并完善了代码逻辑和文件管理。

环境:

树莓派4b

Raspberry Pi OS with desktop 2021.1.11

亚博智能摄像头

摄像头操作

1、摄像头必须插入板子靠中间的排线接口,插好后摄像头板面不亮红灯(插入板子末端SD卡背面的排线接口,摄像头板面会亮红灯,且系统无法识别)

2、开启摄像头

sudo raspi-config
#进入Interfacing Options
#Enable Camera

sudo reboot

3、摄像头操作命令

raspistill		                     #获取静态图片
raspistill -t 1000 -o image.jpg    #延迟1秒钟拍摄名为image.jpg的照片
raspivid			                     #获取视频信息

照相机相关操作

准备工作

安装依赖包:

#安装zbar(暂时不管中文支持的问题)

#方法一
sudo apt-get install python-zbar
python3
import zbar
#方法二
wget  http://downloads.sourceforge.net/project/zbar/zbar/0.10/zbar-0.10.tar.gz
tar -zvxf  zbar-0.10.tar.gz 
sudo apt-get install python-gtk2-dev 
sudo apt-get install libqt4-dev
cd zbar-0.10
./configure --without-imagemagick -disable-video  -without-qt  -without-gtk  -without-x
make
python3
import zbar

zbar的安装过程借鉴于此

#安装PIL和pillow

代码实现

文件逻辑:

colorList.py
whole_code.py
lry_color.py
lry_realize.py
lry_scance.py
lry_takezbar.py
project
pi

调用逻辑:

colorList.py
lry_color.py
lry_takep.py
whole_code.py
lry_scance.py
lry_takezbar.py
project

颜色识别

1、颜色库

文件名:colorList.py

代码:

#colorList颜色库
import numpy as np
import collextions

def getColorList():
  dict = collections.defaultdict(list)
  
  #black
  lower_black = np.array([0,0,0])
  upper_black = np.array([180,255,46])
  color_list_black = []
  color_list_black.append(lower_black)
  color_list_black.append(upper_black)
  dict['black'] = color_list_black
  
  #gray
  lower_gray = np.array([0,0,46])
  upper_gray = np.array([180,43,220])
  color_list_gray = []
  color_list_gray.append(lower_gray)
  color_list_gray.append(upper_gray)
  dict['gray'] = color_list_gray
  
  #white
  lower_white = np.array([0,0,221])
  upper_white = np.array([190,30,255])
  color_list_white = []
  color_list_white.append(lower_white)
  color_list_white.append(upper_white)
  dict['white'] = color_list_white
  
  #red
  lower_red = np.array([156,43,46])
  upper_red = np.array([180,255,255])
  color_list_red = []
  color_list_red.append(lower_red)
  color_list_red.append(upper_red)
  dict['red'] = color_list_red
  
  #red2
  lower_red2 = np.array([0,43,46])
  upper_red2 = np.array([10,255,255])
  color_list_red2 = []
  color_list_red2.append(lower_red2)
  color_list_red2.append(upper_red2)
  dict['red2'] = color_list_red2
  
  #orange
  lower_orange = np.array([11,43,46])
  upper_orange = np.array([25,255,255])
  color_list_orange = []
  color_list_orange.append(lower_orange)
  color_list_orange.append(upper_orange)
  dict['orange'] = color_list_orange
  
  #yellow
  lower_yellow = np.array([])
  upper_yellow = np.array([])
  color_list_yellow = []
  color_list_yellow.append(lower_yellow)
  color_list_yellow.append(upper_yellow)
  dict['yellow'] = color_list_yellow
  
  #green
  lower_green = np.array([35,43,46])
  upper_green = np.array([77,255,255])
  color_list_green = []
  color_list_green.append(lower_green)
  color_list_green.append(upper_green)
  dict['green'] = color_list_green
  
  #cyan
  lower_cyan = np.array([78,43,46])
  upper_cyan = np.array([99,255,255])
  color_list_cyan = []
  color_list_cyan.append(lower_cyan)
  color_list_cyan.append(upper_cyan)
  dict['cyan'] = color_list_cyan
  
  #blue
  lower_blue = np.array([100,43,46])
  upper_blue = np.array([124,255,255])
  color_list_blue = []
  color_list_blue.append(lower_blue)
  color_list_blue.append(upper_blue)
  dict['blue'] = color_list_blue
  
  #purple
  lower_purple = np.array([125,43,46])
  upper_purple = np.array([155,255,255])
  color_list_purple = []
  color_list_purple.append(lower_purple)
  color_list_purple.append(upper_purple)
  dict['purple'] = color_list_purple
  
  return dict

if __name__ == '__main__':
  color_dict = getColorList()
  print(color_dict)
  
  num = len(color_dict)
  print('num=',num)
  
  for d in color_dict:
    print('key=',d)
    print('value=',color_dict[d][1])
    

2、识别

文件名:lry_color.py

代码:

#lry_color.py
import cv2
import colorList


def get_color(frame):
    # print('go in get_color')
    hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
    maxsum = 0
    color = None
    color_dict = colorList.getColorList()
    for d in color_dict:
        mask = cv2.inRange(hsv, color_dict[d][0], color_dict[d][1])
        # cv2.imwrite(d + ".png", mask)
        binary = cv2.threshold(mask, 127, 255, cv2.THRESH_BINARY)[1]
        binary = cv2.dilate(binary, None, iterations=2)
        # cv2.imwrite(d +"1.png", binary)
        cnts = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2]
        sum = 0
        for c in cnts:
            sum += cv2.contourArea(c)
        # print("%s  , %d" %(d, sum ))
        if sum > maxsum:
            maxsum = sum
            color = d
    return color


if __name__ == '__main__':
    filename = "./images/takephoto2.jpg"
    frame = cv2.imread(filename)
    print(get_color(frame))

3、识别颜色时调用摄像头

文件名:lry_takep.py

代码:

#lry_takep.py
import cv2            
import lry_color
import time

def videox_color():
    vix = cv2.VideoCapture(0)
    while True:
        ret, tu = vix.read()
        #cv2.imshow("take_photo", tu)
        cv2.waitKey(1)
        cv2.imwrite("./images/color.png", tu)
        filename = cv2.imread("./images/color.png")
        color = xf_color.get_color(filename)

        if color == "red" or color == "red2":
            print("red")
            result = "1"
            break
        elif color == "green":
            print("green")
            result = "2"
            break
        elif color == "blue":
            print("blue")
            result = "3"
            break
    vix.release()
    cv2.destroyAllWindows()
    return result


if __name__ == '__main__':
    #time.sleep(20)
    videox_color()

识别二维码

1、二维码识别

文件名:lry_scance.py

代码:

#lry_scance.py
import pyzbar.pyzbar as pyzbar
#import zbar
from PIL import Image, ImageEnhance


def scance():

    image = "./images/photo.png"

    img = Image.open(image)

    # img = ImageEnhance.Brightness(img).enhance(2.0)  # 增加亮度
    #
    # img = ImageEnhance.Sharpness(img).enhance(17.0)  # 锐利化
    #
    img = ImageEnhance.Contrast(img).enhance(4.0)  # 增加对比度
    #
    img = img.convert('L')  # 灰度化

    barcodes = pyzbar.decode(img)

    for barcode in barcodes:
        barcodeData = barcode.data.decode("utf-8")
        return barcodeData


if __name__ == '__main__':
    scance()

2、调用摄像头扫描二维码

文件名:lry_takezbar.py

代码‘:

#lry_takezbar.py
import cv2
import lry_scance
import time

def videox_qr():
    vix = cv2.VideoCapture(0)
    while True:
        ret, tu = vix.read()
        cv2.imshow("take_photo", tu)
        cv2.waitKey(1)
        cv2.imwrite("./images/photo.png", tu)
        result = xf_scance.scance()
        if result:
            # print(result)
            break
    vix.release()
    cv2.destroyAllWindows()
    return result


if __name__ == '__main__':
    #time.sleep(30)
    r = videox_qr()
    print(r)

合成整理代码

文件名:whole_programe.py

代码:

#whole_programe.py
import os
import sys 
import time
import logging
import spidev as SPI
sys.path.append("..")
from lib import LCD_2inch4
from PIL import Image,ImageDraw,ImageFont
import cv2
import lry_scance
import lry_color
import serial    #导入serial库




#qrcode  
def videox_qr():
    vix = cv2.VideoCapture(0)
    while True:
        ret, tu = vix.read()
        #cv2.imshow("take_photo", tu)
        cv2.waitKey(1)
        cv2.imwrite("./images/photo.png", tu)
        result = xf_scance.scance()
        if (result!=""):
            #print(result)
            break
    vix.release()
    cv2.destroyAllWindows()
    return result

# whole value

#qr_result = "121+121"
#up_order = "121"
#low_order = "131"
#print(up_order)
#print(low_order)

def qr_scan():
    qr_result=videox_qr()
    #print(qr_result)
    up_order = qr_result[0:3]
    low_order = qr_result[4:]
    #print(up_order)
    #print(low_order)
    #print("split ok")
    return up_order,low_order,qr_result
    
# screen

def screen():
    # Raspberry Pi pin configuration:
    RST = 27
    DC = 25
    BL = 18
    bus = 0 
    device = 0 
    #logging.basicConfig(level=logging.DEBUG)
    try:
        # display with hardware SPI:
        ''' Warning!!!Don't  creation of multiple displayer objects!!! '''
        #disp = LCD_2inch4.LCD_2inch4(spi=SPI.SpiDev(bus, device),spi_freq=10000000,rst=RST,dc=DC,bl=BL)
        disp = LCD_2inch4.LCD_2inch4()
        # Initialize library.
        disp.Init()
        # Clear display.
        disp.clear()

        # Create blank image for drawing.
        image1 = Image.new("RGB", (disp.width, disp.height ), "WHITE")
        draw = ImageDraw.Draw(image1)
        
        #drawing txet 
        #logging.info("draw text")
        Font1 = ImageFont.truetype("./Font/Font01.ttf",25)
        Font2 = ImageFont.truetype("./Font/Font01.ttf",35)
        Font3 = ImageFont.truetype("./Font/Font02.ttf",90)
        
        text_1,text_2,qr_resulttext = qr_scan()
        #text_1= u"123"
        draw.text((20,0),text_1, fill = "BLACK",font=Font3)
        
        #text_2= u"321"
        draw.text((20,140),text_2, fill = "BLACK",font=Font3)
        
        text_3= u"+"
        draw.text((30,75),text_3, fill = "BLACK",font=Font3)
        # image rotate
        
        im_r=image1.rotate(180)
        disp.ShowImage(im_r)
        
        disp.module_exit()
    except IOError as e:
        logging.info(e)    
    except KeyboardInterrupt:
        disp.module_exit()
        logging.info("quit:")
        exit()
    

# color
def videox_color():
    vix = cv2.VideoCapture(0)
    while True:
        ret, tu = vix.read()
        #cv2.imshow("take_photo", tu)
        cv2.waitKey(1)
        cv2.imwrite("./images/color.png", tu)
        filename = cv2.imread("./images/color.png")
        color = xf_color.get_color(filename)

        if color == "red" or color == "red2":
            #print("red")
            result = "1"  #
            break
        elif color == "green":
            #print("green")
            result = "2" #2
            break
        elif color == "blue":
            #print("blue")
            result = "3" #3
            break
    vix.release()
    cv2.destroyAllWindows()
    return result

def order(color_result,color_order):
    i= 0
    result = color_order.index(color_result)
    result = (result +1)
    return result 
        
    

#  "321"  --->>  abcdef  
def change_order(order):
    result = '1'
    if(order=="123"):
        result = 'a'
    elif(order=="132"):
        result = 'b'
    elif(order=="213"):
        result = 'c'
    elif(order=="231"):
        result = 'd'
    elif(order=="312"):
        result = 'e'
    elif(order=="321"):
        result = 'f'
    return result

#   123---->   abc   
def change_number(number):
    result = '1'
    if(number==1):
        result = 'x'
    elif(number==2):
        result = 'y'
    elif(number==3):
        result = 'z'
    return result

""""def getresp():
    while 1:
        resp = ser.readline().decode()#用response读取端口的返回值
        if(resp!=""):
            return resp"""


# color   videox_color
# qrcode   videox_qr

#up_order,low_order,qr_result = qr_scan()
#print(up_order)
#print(low_order)
#  screen()    # qr_code + screen
#time.sleep(20)
ser = serial.Serial('/dev/ttyACM0', 9600,timeout=1.5);

try:
    screen()
    #up_order,low_order,qr_result = qr_scan()
    #screen()
   
    #up_order = "213"
    #low_order = "231"
    #print("qr code&screen  sending")
    while 1:
        
        send = '1'
        #print("qr code sending")
        ser.write(send.encode())#写s字符
        #print("sending is ok ")
        time.sleep(1)
        response = ser.readline().decode()#用response读取端口的返回值
        #print("geting response")
        #print (response);#进行打印
        if(response != ""):
               
            #print(response)
            if(response=="2\r\n"):
                
                #print("gived up order")
                #up_number = change(up_order)
                #print("uporder change is ok")
                
                # zhuanhuan  wei abcdef  
                re_2 = change_order(up_order)
                #  
                #ser.write(re_2.encode())
                #print("gived up order",re_2)
                
                #print(up_number)
                break
            """
                while 1:
                    ser.write(re_2.encode())
                    
                    rep_2 = ser.readline().decode()
                    if(rep_2!= ""):
                        
                        break
                #rep_2 = getresp()
                        #print("2_order rep is ok")
                        #print(rep_2)
                
                
                
                
            elif(response=="3\r\n"):
                #print("gived low order")
                #low_number = change(low_order)
                #print("loworder change is ok")
                
                re_3 = change_order(low_order)
                #print("low order",low_order)
                #ser.write(re_3.encode())
                #print("gived low order",re_3)
                #print(low_number)
                
                #sleep.time(1)
                while 1:
                    ser.write(re_3.encode())
                    #print("gived low order:",re_2)
                    #time.sleep(1)
                    rep_3 = ser.readline().decode()
                    if(rep_3!= ""):
                    
                        #print("3_order rep is ok")
                        #print(rep_3)
                        break
                
                
                
            elif(response=="4\r\n"):
                #print("4_color")
                color_result = videox_color()
                #print("4_color is ok next color number")
                color_number = order(color_result,up_order)
                #   123---->   abc   
                color_re4 = change_number(color_number)
                
                #time.sleep(1)
                #color_number = change(color_number)
                ##########################################################################################
                #print("4_color number is ok:",color_re4)
                ser.write(color_re4.encode())
                
                #print("4_color number is sending ")
                #ser.write(color_number.encode())
                #time.sleep(1)
                #rep_4 = ser.readline().decode()
                while 1:
                    #time.sleep(2)
                    ser.write(color_re4.encode())
                    #print("geting rep_4")
                    rep_4 = ser.readline().decode()
                    if(rep_4!= ""):
                    
                        #print("4_color response is ok")
                        #print(rep_4)
                        break
                #print("4_color response is ok ")"""
                
                
                
            """elif(response=="5\r\n"):
                #print("5_color")
                color_result = videox_color()
                #print("5_color is ok next color number")
                color_number = order(color_result,low_order)
                color_re5 = change_number(color_number)
#                 color_number = change(color_number)
                #print("5_color number is ok:",color_re5)
                #ser.write(color_re5.encode())
                
                #print("5_color number  response ")
                #rep_5 = ser.readline().decode()
                while 1:
                    ser.write(color_re5.encode())
                    #time.sleep(2)
                    rep_5 = ser.readline().decode()
                    if(rep_5!= ""):
                    
                        #print("5_color response is ok")
                        #print(rep_5)
                        break"""
             
                
          
     
      
except:
    
    print("error")
    ser.close();#抛出异常后关闭端口

注:whole_program.py中包含 树莓派和arduino的串口通信内容,是小组内学长 @redflowe 改动过的程序。

你可能感兴趣的:(树莓派,opencv)