Computer Vision | Machine Vision | Machine Learning | Deep Learning
Editor’s Note
The Raspberry Pi is one of the earliest popular embedded Linux boards, essentially a small computer the size of a credit card. You can connect the Raspberry Pi to a TV, monitor, keyboard, mouse, and use it as a normal Linux computer; it also supports Windows now.
Author: woshigaowei5146 @CSDN
Table of Contents
Record
content
Preparation
Configuration
Testing
Program
Color Recognition Tracking
Face Recognition
Gesture Recognition
Shape Recognition
Barcode Recognition
QR Code Recognition
Troubleshooting
Preparation
-
Raspberry Pi 4B
-
USB Plug-and-Play Camera
Configuration
Install python-opencv, reference: https://blog.csdn.net/weixin_45911959/article/details/122709090
Install numpy, pip3 install-U numpy
Install opencv-python, opencv-contrib-python, reference: https://blog.csdn.net/weixin_57605235/article/details/121512923
Testing
Image:
import cv2
a=cv2.imread("/home/pi/2020-06-15-162551_1920x1080_scrot.png")
cv2.imshow("test", a)
cv2.waitKey()
cv2.destroyAllWindows()
Video:
import cv2
cap = cv2.VideoCapture(0)
while True:
ret, frame = cap.read()
cv2.imshow('frame', frame)
# This step is necessary, otherwise the image cannot be displayed
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# When everything is done, release the capture
cap.release()
cv2.destroyAllWindows()
Program
Color Recognition Tracking
import sys
import cv2
import math
import time
import threading
import numpy as np
import HiwonderSDK.yaml_handle as yaml_handle
if sys.version_info.major == 2:
print('Please run this program with python3!')
sys.exit(0)
range_rgb = {
'red': (0, 0, 255),
'blue': (255, 0, 0),
'green': (0, 255, 0),
'black': (0, 0, 0),
'white': (255, 255, 255)}
__target_color = ('red', 'green', 'blue')
lab_data = yaml_handle.get_yaml_data(yaml_handle.lab_file_path)
# Find the largest contour
# Parameters are the list of contours to compare
def getAreaMaxContour(contours):
contour_area_temp = 0
contour_area_max = 0
area_max_contour = None
for c in contours: # Traverse all contours
contour_area_temp = math.fabs(cv2.contourArea(c)) # Calculate contour area
if contour_area_temp > contour_area_max:
contour_area_max = contour_area_temp
if contour_area_temp > 300: # Only valid if the maximum area contour is greater than 300, to filter interference
area_max_contour = c
return area_max_contour, contour_area_max # Return the largest contour
detect_color = None
color_list = []
start_pick_up = False
size = (640, 480)
def run(img):
global rect
global detect_color
global start_pick_up
global color_list
img_copy = img.copy()
frame_resize = cv2.resize(img_copy, size, interpolation=cv2.INTER_NEAREST)
frame_gb = cv2.GaussianBlur(frame_resize, (3, 3), 3)
frame_lab = cv2.cvtColor(frame_gb, cv2.COLOR_BGR2LAB) # Convert the image to LAB space
color_area_max = None
max_area = 0
areaMaxContour_max = 0
if not start_pick_up:
for i in lab_data:
if i in __target_color:
frame_mask = cv2.inRange(frame_lab,
(lab_data[i]['min'][0],
lab_data[i]['min'][1],
lab_data[i]['min'][2]),
(lab_data[i]['max'][0],
lab_data[i]['max'][1],
lab_data[i]['max'][2])) # Perform bitwise operation on the original image and mask
opened = cv2.morphologyEx(frame_mask, cv2.MORPH_OPEN, np.ones((3, 3), np.uint8)) # Open operation
closed = cv2.morphologyEx(opened, cv2.MORPH_CLOSE, np.ones((3, 3), np.uint8)) # Close operation
contours = cv2.findContours(closed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[-2] # Find contours
areaMaxContour, area_max = getAreaMaxContour(contours) # Find the maximum contour
if areaMaxContour is not None:
if area_max > max_area: # Find the maximum area
max_area = area_max
color_area_max = i
areaMaxContour_max = areaMaxContour
if max_area > 500: # Found the maximum area
rect = cv2.minAreaRect(areaMaxContour_max)
box = np.int0(cv2.boxPoints(rect))
y = int((box[1][0]-box[0][0])/2+box[0][0])
x = int((box[2][1]-box[0][1])/2+box[0][1])
print('X:',x,'Y:',y) # Print coordinates
cv2.drawContours(img, [box], -1, range_rgb[color_area_max], 2)
if not start_pick_up:
if color_area_max == 'red': # Red maximum
color = 1
elif color_area_max == 'green': # Green maximum
color = 2
elif color_area_max == 'blue': # Blue maximum
color = 3
else:
color = 0
color_list.append(color)
if len(color_list) == 3: # Multiple judgments
# Take the average
color = int(round(np.mean(np.array(color_list))))
color_list = []
if color == 1:
detect_color = 'red'
elif color == 2:
detect_color = 'green'
elif color == 3:
detect_color = 'blue'
else:
detect_color = 'None'
## cv2.putText(img, "Color: " + detect_color, (10, img.shape[0] - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.65, detect_color, 2)
return img
if __name__ == '__main__':
cap = cv2.VideoCapture(-1) # Read the camera
__target_color = ('red',)
while True:
ret, img = cap.read()
if ret:
frame = img.copy()
Frame = run(frame)
cv2.imshow('Frame', Frame)
key = cv2.waitKey(1)
if key == 27:
break
else:
time.sleep(0.01)
cv2.destroyAllWindows()
Effect:
Face Recognition
Utilizes a face dataset trained with Caffe.
import sys
import numpy as np
import cv2
import math
import time
import threading
# Face detection
if sys.version_info.major == 2:
print('Please run this program with python3!')
sys.exit(0)
# Threshold
conf_threshold = 0.6
# Model location
modelFile = "/home/pi/mu_code/models/res10_300x300_ssd_iter_140000_fp16.caffemodel"
configFile = "/home/pi/mu_code/models/deploy.prototxt"
net = cv2.dnn.readNetFromCaffe(configFile, modelFile)
frame_pass = True
x1=x2=y1=y2 = 0
old_time = 0
def run(img):
global old_time
global frame_pass
global x1,x2,y1,y2
if not frame_pass:
frame_pass = True
cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2, 8)
x1=x2=y1=y2 = 0
return img
else:
frame_pass = False
img_copy = img.copy()
img_h, img_w = img.shape[:2]
blob = cv2.dnn.blobFromImage(img_copy, 1, (100, 100), [104, 117, 123], False, False)
net.setInput(blob)
detections = net.forward() # Compute recognition
for i in range(detections.shape[2]):
confidence = detections[0, 0, i, 2]
if confidence > conf_threshold:
# Convert the coordinates of the detected person to unscaled coordinates
x1 = int(detections[0, 0, i, 3] * img_w)
y1 = int(detections[0, 0, i, 4] * img_h)
x2 = int(detections[0, 0, i, 5] * img_w)
y2 = int(detections[0, 0, i, 6] * img_h)
cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2, 8) # Draw a rectangle around the detected face
X = (x1 + x2)/2
Y = (y1 + y2)/2
print('X:',X,'Y:',Y)
return img
if __name__ == '__main__':
cap = cv2.VideoCapture(-1) # Read the camera
while True:
ret, img = cap.read()
if ret:
frame = img.copy()
Frame = run(frame)
cv2.imshow('Frame', Frame)
key = cv2.waitKey(1)
if key == 27:
break
else:
time.sleep(0.01)
cv2.destroyAllWindows()
Gesture Recognition
import os
import sys
import cv2
import math
import time
import numpy as np
import HiwonderSDK.Misc as Misc
if sys.version_info.major == 2:
print('Please run this program with python3!')
sys.exit(0)
__finger = 0
__t1 = 0
__step = 0
__count = 0
__get_finger = False
# Initial position
def initMove():
pass
def reset():
global __finger, __t1, __step, __count, __get_finger
__finger = 0
__t1 = 0
__step = 0
__count = 0
__get_finger = False
def init():
reset()
initMove()
class Point(object): # A coordinate point
x = 0
y = 0
def __init__(self, x=0, y=0):
self.x = x
self.y = y
class Line(object): # A line
def __init__(self, p1, p2):
self.p1 = p1
self.p2 = p2
def GetCrossAngle(l1, l2):
'''
Calculate the angle between two lines
:param l1:
:param l2:
:return:
'''
arr_0 = np.array([(l1.p2.x - l1.p1.x), (l1.p2.y - l1.p1.y)])
arr_1 = np.array([(l2.p2.x - l2.p1.x), (l2.p2.y - l2.p1.y)])
cos_value = (float(arr_0.dot(arr_1)) / (np.sqrt(arr_0.dot(arr_0))
* np.sqrt(arr_1.dot(arr_1)))) # Note to convert to floating point operation
return np.arccos(cos_value) * (180/np.pi)
def distance(start, end):
"""
Calculate the distance between two points
:param start: Start point
:param end: End point
:return: Returns the distance between two points
"""
s_x, s_y = start
e_x, e_y = end
x = s_x - e_x
y = s_y - e_y
return math.sqrt((x**2)+(y**2))
def image_process(image, rw, rh): # hsv
'''
# Light influence, please modify the range of cb
# Normal yellow-skinned people's Cr component is about between 140~160
Recognize skin color
:param image: Image
:return: Recognized binary image
'''
frame_resize = cv2.resize(image, (rw, rh), interpolation=cv2.INTER_CUBIC)
YUV = cv2.cvtColor(frame_resize, cv2.COLOR_BGR2YCR_CB) # Convert the image to YCrCb
_, Cr, _ = cv2.split(YUV) # Split YCrCb
Cr = cv2.GaussianBlur(Cr, (5, 5), 0)
_, Cr = cv2.threshold(Cr, 135, 160, cv2.THRESH_BINARY +
cv2.THRESH_OTSU) # OTSU Binarization
# Open operation, remove noise
open_element = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
opend = cv2.morphologyEx(Cr, cv2.MORPH_OPEN, open_element)
# Erosion
kernel = np.ones((3, 3), np.uint8)
erosion = cv2.erode(opend, kernel, iterations=3)
return erosion
def get_defects_far(defects, contours, img):
'''
Get the farthest point in the convex hull
'''
if defects is None and contours is None:
return None
far_list = []
for i in range(defects.shape[0]):
s, e, f, d = defects[i, 0]
start = tuple(contours[s][0])
end = tuple(contours[e][0])
far = tuple(contours[f][0])
# Calculate the distance between two points
a = distance(start, end)
b = distance(start, far)
c = distance(end, far)
# Find the angle between the fingers
angle = math.acos((b ** 2 + c ** 2 - a ** 2) /
(2 * b * c)) * 180 / math.pi
# The angle between fingers is generally not greater than 100 degrees
# Less than 90 degrees
if angle <= 75: # 90:
# cv.circle(img, far, 10, [0, 0, 255], 1)
far_list.append(far)
return far_list
def get_max_coutour(cou, max_area):
'''
Find the largest contour
Calculate the area, find the maximum, and determine if it is less than the minimum area, if less, abandon
:param cou: Contour
:return: Return the largest contour
'''
max_coutours = 0
r_c = None
if len(cou) < 1:
return None
else:
for c in cou:
# Calculate area
temp_coutours = math.fabs(cv2.contourArea(c))
if temp_coutours > max_coutours:
max_coutours = temp_coutours
cc = c
# Determine the maximum area among all contours
if max_coutours > max_area:
r_c = cc
return r_c
def find_contours(binary, max_area):
'''
CV_RETR_EXTERNAL - Only extract the outermost contour
CV_RETR_LIST - Extract all contours, and place them in a list
CV_RETR_CCOMP - Extract all contours and organize them into a two-layer hierarchy: the top layer is the boundary of the connected domain, and the lower layer is the inner boundary of the hole.
CV_RETR_TREE - Extract all contours and reconstruct all hierarchy of nested contours
method Approximation method (for all nodes, excluding those using internal approximation CV_RETR_RUNS).
CV_CHAIN_CODE - Output contour of Freeman chain code. Other methods output polygon (point sequence).
CV_CHAIN_APPROX_NONE - Translate all points from chain code form to point sequence form
CV_CHAIN_APPROX_SIMPLE - Compress horizontal, vertical and diagonal segments, that is, the function only retains the end pixel points;
CV_CHAIN_APPROX_TC89_L1,
CV_CHAIN_APPROX_TC89_KCOS - Apply Teh-Chin chain approximation algorithm. CV_LINK_RUNS - Use a completely different contour extraction algorithm by connecting horizontal fragments of 1
:param binary: Input binary image
:return: Return the maximum contour
'''
# Find all contours
contours = cv2.findContours(
binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[-2]
# Return the maximum contour
return get_max_coutour(contours, max_area)
def get_hand_number(binary_image, contours, rw, rh, rgb_image):
'''
:param binary_image:
:param rgb_image:
:return:
'''
# # 2、Find the position of the fingertip
# # Find contours, return maximum contour
x = 0
y = 0
coord_list = []
new_hand_list = [] # Get the final finger coordinates
if contours is not None:
# Perimeter 0.035 Modify according to recognition situation, the better the recognition, the smaller
epsilon = 0.020 * cv2.arcLength(contours, True)
# Contour similarity
approx = cv2.approxPolyDP(contours, epsilon, True)
# cv2.approxPolyDP()'s parameter 2 (epsilon) is a distance value, representing the degree of closeness of the polygon contour to the actual contour, the smaller the value, the more accurate; parameter 3 indicates whether it is closed
# cv2.polylines(rgb_image, [approx], True, (0, 255, 0), 1)# Draw polygon
if approx.shape[0] >= 3: # More than three points # A polygon needs at least three points
approx_list = []
for j in range(approx.shape[0]): # Store all points of the polygon in a list
# cv2.circle(rgb_image, (approx[j][0][0],approx[j][0][1]), 5, [255, 0, 0], -1)
approx_list.append(approx[j][0])
approx_list.append(approx[0][0]) # Add the first point at the end
approx_list.append(approx[1][0]) # Add the second point at the end
for i in range(1, len(approx_list) - 1):
p1 = Point(approx_list[i - 1][0],
approx_list[i - 1][1]) # Declare a point
p2 = Point(approx_list[i][0], approx_list[i][1])
p3 = Point(approx_list[i + 1][0], approx_list[i + 1][1])
line1 = Line(p1, p2) # Declare a line
line2 = Line(p2, p3)
angle = GetCrossAngle(line1, line2) # Get the angle between the two lines
angle = 180 - angle #
# print angle
if angle < 42: # Get the angle between the two intersecting lines, and less than 37 degrees
#cv2.circle(rgb_image, tuple(approx_list[i]), 5, [255, 0, 0], -1)
coord_list.append(tuple(approx_list[i]))
##############################################################################
# Remove points between the fingers
# 1、Get the farthest points in the convex hull
#cv2.drawContours(rgb_image, contours, -1, (255, 0, 0), 1)
try:
hull = cv2.convexHull(contours, returnPoints=False)
# Find convex hull defects. The returned data is 【start point, end point, farthest point, approximate distance to the farthest point】
defects = cv2.convexityDefects(contours, hull)
# Return the coordinates between the fingers
hand_coord = get_defects_far(defects, contours, rgb_image)
except:
return rgb_image, 0
# 2、Remove the farthest point from coord_list
alike_flag = False
if len(coord_list) > 0:
for l in range(len(coord_list)):
for k in range(len(hand_coord)):
if (-10 <= coord_list[l][0] - hand_coord[k][0] <= 10 and
-10 <= coord_list[l][1] - hand_coord[k][1] <= 10): # Compare along the X,Y axes, remove those that are close
alike_flag = True
break #
if alike_flag is False:
new_hand_list.append(coord_list[l])
alike_flag = False
# Get the coordinates of the fingertips and display
for i in new_hand_list:
j = list(tuple(i))
j[0] = int(Misc.map(j[0], 0, rw, 0, 640))
j[1] = int(Misc.map(j[1], 0, rh, 0, 480))
cv2.circle(rgb_image, (j[0], j[1]), 20, [0, 255, 255], -1)
fingers = len(new_hand_list)
return rgb_image, fingers
def run(img, debug=False):
global __act_map, __get_finger
global __step, __count, __finger
binary = image_process(img, 320, 240)
contours = find_contours(binary, 3000)
img, finger = get_hand_number(binary, contours, 320, 240, img)
if not __get_finger:
if finger == __finger:
__count += 1
else:
__count = 0
__finger = finger
cv2.putText(img, "Finger(s):%d" % __finger, (50, 480 - 30),
cv2.FONT_HERSHEY_SIMPLEX, 1.2, (0, 255, 255), 2)# Write the number of fingers recognized on the image
return img
if __name__ == '__main__':
init()
cap = cv2.VideoCapture(-1) # Read the camera
while True:
ret, img = cap.read()
if ret:
frame = img.copy()
Frame = run(frame)
frame_resize = cv2.resize(Frame, (320, 240))
cv2.imshow('frame', frame_resize)
key = cv2.waitKey(1)
if key == 27:
break
else:
time.sleep(0.01)
cv2.destroyAllWindows()
Shape Recognition
import sys
import cv2
import math
import time
import threading
import numpy as np
import HiwonderSDK.tm1640 as tm
import RPi.GPIO as GPIO
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
color_range = {
'red': [(0, 101, 177), (255, 255, 255)],
'green': [(47, 0, 135), (255, 119, 255)],
'blue': [(0, 0, 0), (255, 255, 115)],
'black': [(0, 0, 0), (41, 255, 136)],
'white': [(193, 0, 0), (255, 250, 255)],
}
if sys.version_info.major == 2:
print('Please run this program with python3!')
sys.exit(0)
range_rgb = {
'red': (0, 0, 255),
'blue': (255, 0, 0),
'green': (0, 255, 0),
'black': (0, 0, 0),
'white': (255, 255, 255),
}
# Find the largest contour
# Parameters are the list of contours to compare
def getAreaMaxContour(contours):
contour_area_temp = 0
contour_area_max = 0
area_max_contour = None
for c in contours: # Traverse all contours
contour_area_temp = math.fabs(cv2.contourArea(c)) # Calculate contour area
if contour_area_temp > contour_area_max:
contour_area_max = contour_area_temp
if contour_area_temp > 50: # Only valid if the maximum area contour is greater than 50, to filter interference
area_max_contour = c
return area_max_contour, contour_area_max # Return the largest contour
shape_length = 0
def move():
global shape_length
while True:
if shape_length == 3:
print('Triangle')
## Display 'Triangle'
tm.display_buf = (0x80, 0xc0, 0xa0, 0x90, 0x88, 0x84, 0x82, 0x81,
0x81, 0x82, 0x84,0x88, 0x90, 0xa0, 0xc0, 0x80)
tm.update_display()
elif shape_length == 4:
print('Rectangle')
## Display 'Rectangle'
tm.display_buf = (0x00, 0x00, 0x00, 0x00, 0xff, 0x81, 0x81, 0x81,
0x81, 0x81, 0x81,0xff, 0x00, 0x00, 0x00, 0x00)
tm.update_display()
elif shape_length >= 6:
print('Circle')
## Display 'Circle'
tm.display_buf = (0x00, 0x00, 0x00, 0x00, 0x1c, 0x22, 0x41, 0x41,
0x41, 0x22, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00)
tm.update_display()
time.sleep(0.01)
# Run sub-thread
th = threading.Thread(target=move)
th.setDaemon(True)
th.start()
shape_list = []
action_finish = True
if __name__ == '__main__':
cap = cv2.VideoCapture(-1)
while True:
ret,img = cap.read()
if ret:
img_copy = img.copy()
img_h, img_w = img.shape[:2]
frame_gb = cv2.GaussianBlur(img_copy, (3, 3), 3)
frame_lab = cv2.cvtColor(frame_gb, cv2.COLOR_BGR2LAB) # Convert the image to LAB space
max_area = 0
color_area_max = None
areaMaxContour_max = 0
if action_finish:
for i in color_range:
if i != 'white':
frame_mask = cv2.inRange(frame_lab, color_range[i][0], color_range[i][1]) # Perform bitwise operation on the original image and mask
opened = cv2.morphologyEx(frame_mask, cv2.MORPH_OPEN, np.ones((6,6),np.uint8)) # Open operation
closed = cv2.morphologyEx(opened, cv2.MORPH_CLOSE, np.ones((6,6),np.uint8)) # Close operation
contours = cv2.findContours(closed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[-2] # Find contours
areaMaxContour, area_max = getAreaMaxContour(contours) # Find the maximum contour
if areaMaxContour is not None:
if area_max > max_area:# Find the maximum area
max_area = area_max
color_area_max = i
areaMaxContour_max = areaMaxContour
if max_area > 200:
cv2.drawContours(img, areaMaxContour_max, -1, (0, 0, 255), 2)
# Recognize shape
# Perimeter 0.035 Modify according to recognition situation, the better the recognition, the smaller
epsilon = 0.035 * cv2.arcLength(areaMaxContour_max, True)
# Contour similarity
approx = cv2.approxPolyDP(areaMaxContour_max, epsilon, True)
shape_list.append(len(approx))
if len(shape_list) == 30:
shape_length = int(round(np.mean(shape_list)))
shape_list = []
print(shape_length)
frame_resize = cv2.resize(img, (320, 240))
cv2.imshow('frame', frame_resize)
key = cv2.waitKey(1)
if key == 27:
break
else:
time.sleep(0.01)
my_camera.camera_close()
cv2.destroyAllWindows()
approxPolyDP() function is used to approximate a continuous smooth curve into a polygon.
For example, in the code “approx=cv2.approxPolyDP(areaMaxContour_max,epsilon,True)”, the parameters in parentheses are as follows:
The first parameter “areaMaxContour_max” is the input shape contour;
The second parameter “epsilon” is the distance value, representing the degree of closeness of the polygon contour to the actual contour, the smaller the value, the more accurate;
The third parameter “True” indicates that the contour is a closed curve.
The output of the cv2.approxPolyDP() function is the vertex coordinates of the approximate polygon, which is used to determine the shape based on the number of vertices.
Barcode Recognition
First install pyzbar, pip3 install pyzbar
import cv2
import sys
from pyzbar import pyzbar
if sys.version_info.major == 2:
print('Please run this program with python3!')
sys.exit(0)
def run(image):
# Find the barcode in the image and decode each barcode
barcodes = pyzbar.decode(image)
# Loop through detected barcodes
for barcode in barcodes:
# Extract the bounding box position of the barcode
(x, y, w, h) = barcode.rect
# Draw a rectangle around the barcode in the image
cv2.rectangle(image, (x, y), (x + w, y + h), (0, 0, 255), 2)
barcodeData = barcode.data.decode("utf-8")
barcodeType = barcode.type
# Draw the barcode data and barcode type on the image
text = "{} ({})".format(barcodeData, barcodeType)
cv2.putText(image, text, (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
return image
if __name__ == '__main__':
cap = cv2.VideoCapture(-1) # Read the camera
while True:
ret, img = cap.read()
if ret:
frame = img.copy()
Frame = run(frame)
cv2.imshow('Frame', Frame)
key = cv2.waitKey(1)
if key == 27:
break
else:
time.sleep(0.01)
cv2.destroyAllWindows()
QR Code Recognition
Install apriltag, found installation failed. Still the old method of downloading locally and then installing.
At https://www.piwheels.org/simple/apriltag/, I downloaded apriltag-0.0.16-cp37-cp37m-linux_armv7l.whl.
Use FileZilla to transfer to Raspberry Pi, open the directory where the whl file is located on Raspberry Pi, install the whl file, and it shows successful installation.
cd /home/pi/Downloads
sudo pip3 install apriltag-0.0.16-cp37-cp37m-linux_armv7l.whl
import sys
import cv2
import math
import time
import threading
import numpy as np
import apriltag
#apriltag detection
if sys.version_info.major == 2:
print('Please run this program with python3!')
sys.exit(0)
object_center_x = 0.0
object_center_y = 0.0
# Detect apriltag
detector = apriltag.Detector(searchpath=apriltag._get_demo_searchpath())
def apriltagDetect(img):
global object_center_x, object_center_y
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
detections = detector.detect(gray, return_image=False)
if len(detections) != 0:
for detection in detections:
corners = np.rint(detection.corners) # Get the four corners
cv2.drawContours(img, [np.array(corners, np.int)], -1, (0, 255, 255), 2)
tag_family = str(detection.tag_family, encoding='utf-8') # Get tag_family
tag_id = int(detection.tag_id) # Get tag_id
object_center_x, object_center_y = int(detection.center[0]), int(detection.center[1]) # Center point
object_angle = int(math.degrees(math.atan2(corners[0][1] - corners[1][1], corners[0][0] - corners[1][0]))) # Calculate rotation angle
return tag_family, tag_id
return None, None
def run(img):
global state
global tag_id
global action_finish
global object_center_x, object_center_y
img_h, img_w = img.shape[:2]
tag_family, tag_id = apriltagDetect(img) # apriltag detection
if tag_id is not None:
print('X:',object_center_x,'Y:',object_center_y)
cv2.putText(img, "tag_id: " + str(tag_id), (10, img.shape[0] - 30), cv2.FONT_HERSHEY_SIMPLEX, 0.65, [0, 255, 255], 2)
cv2.putText(img, "tag_family: " + tag_family, (10, img.shape[0] - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.65, [0, 255, 255], 2)
else:
cv2.putText(img, "tag_id: None", (10, img.shape[0] - 30), cv2.FONT_HERSHEY_SIMPLEX, 0.65, [0, 255, 255], 2)
cv2.putText(img, "tag_family: None", (10, img.shape[0] - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.65, [0, 255, 255], 2)
return img
if __name__ == '__main__':
cap = cv2.VideoCapture(-1) # Read the camera
while True:
ret, img = cap.read()
if ret:
frame = img.copy()
Frame = run(frame)
cv2.imshow('Frame', Frame)
key = cv2.waitKey(1)
if key == 27:
break
else:
time.sleep(0.01)
cv2.destroyAllWindows()
Troubleshooting
module ‘cv2’ has no attribute ‘dnn’
Trying the following commands all had issues, either reporting errors or showing that python-opencv could not be recognized, changing mirrors did not help:
sudo apt install python-opencv or sudo apt install python3-opencv
sudo apt-get install opencv-python
sudo apt-get install opencv-contrib-python
pip install opencv-contrib-python
pip install opencv-python
sudo apt install python-opencv or sudo apt install python3-opencv
sudo apt-get install opencv-python
sudo apt-get install opencv-contrib-python
pip install opencv-contrib-python
pip install opencv-python
Finally, successfully installed by downloading the local file. First, habitually update the Raspberry Pi system and files
sudo apt-get update
sudo apt-get upgrade
If the download speed is too slow, consider changing the source.
1) Use the command " sudo nano /etc/apt/sources.list" to edit the sources.list file, comment out all the contents of the original file, and add the following contents:
deb http://mirrors.aliyun.com/raspbian/raspbian/ buster main contrib non-free rpi
deb-src http://mirrors.aliyun.com/raspbian/raspbian/ buster main contrib non-free rpi
Use Ctrl+O to save the file, Ctrl+X to exit.
2) Use the command "sudo nano /etc/apt/sources.list.d/raspi.list" to edit the raspi.list file, comment out all the contents of the original file, and add the following contents:
deb http://mirrors.tuna.tsinghua.edu.cn/raspbian/raspbian/ buster main
deb-src http://mirrors.tuna.tsinghua.edu.cn/raspbian/raspbian/ buster main
Use Ctrl+O to save the file, Ctrl+X to exit.
3) Execute the command "sudo apt-get update".
4) To speed up the installation speed of Python pip, change the Python software source, the operation method: open the Raspberry Pi command line,
input the following command:
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
pip install pip -U
5) Finally, enter the command "sudo reboot" to restart the Raspberry Pi.
Download the whl file and transfer it to Raspberry Pi, open https://www.piwheels.org/simple/opencv-python/ on the computer,
Download the whl file corresponding to your python version, I downloaded opencv_python-3.4.10.37-cp37-cp37m-linux_armv7l.whl
cp37 indicates the python version, armv7 indicates the processor architecture, Raspberry Pi 4B chooses armv7
Transfer it using FileZilla to Raspberry Pi, open the directory where the whl file is located on Raspberry Pi, install the whl file, and it shows successful installation of opencv-python
cd /home/pi/Downloads
sudo pip3 install opencv_python-3.4.10.37-cp37-cp37m-linux_armv7l.whl
Reference: https://blog.csdn.net/weixin_57605235/article/details/121512923
ImportError:numpy.core.multiarray failed to import
First uninstall the low version of numpy, then install the new version of numpy, that is
pip uninstall numpy
pip install -U numpy
From https://blog.csdn.net/qq_25603827/article/details/107824977
Invalid.
pip install numpy --upgrade --force
From http://www.manongjc.com/article/38668.html
Invalid.
Check the local numpy version:
pip show numpy
When installing opencv-python, the corresponding numpy version is:
So downgrade numpy:
pip install -U numpy==1.14.5 -i https://pypi.mirrors.ustc.edu.cn/simple/
From https://zhuanlan.zhihu.com/p/280702247
Invalid.
Finally, successfully used pip3 install -U numpy. Therefore, it is best to use pip3 for python3. There are many methods tried online, some for upgrading the version, some for downgrading the version, all sorts of strange phenomena emerge, and the statements are inconsistent, reference:
https://blog.csdn.net/Robin_Pi/article/details/120544691 https://zhuanlan.zhihu.com/p/29026597
1121:error:(-2:Unspecified error) FAILED: fs.is_open(). Can’t open
After searching for a long time, I found that there was an extra dot at the beginning.
Focused on Computer Vision and Machine Learning, aiming to make sharing a habit!
Reply in the background to join the mutual assistance group.
Reply “Target Detection” to package and download the relevant materials for target detection.
Reply: Image Processing | Computer Vision | Machine Vision | Machine Learning | Deep Learning | C/C++ | Python | PyTorch | CVPR2022 | Datasets to get the corresponding materials (updated irregularly).