import cv2
import numpy as np
from pyzbar import pyzbar
import webbrowser
# 颜色阈值定义(HSV格式)
color_ranges = {
"red": ([0, 100, 100], [10, 255, 255]),
"green": ([40, 50, 50], [80, 255, 255]),
"blue": ([100, 50, 50], [130, 255, 255]),
"yellow": ([20, 100, 100], [40, 255, 255])
}
def detect_color(hsv_img):
"""识别中心区域颜色"""
h, w = hsv_img.shape[:2]
center_roi = hsv_img[h//2-10:h//2+10, w//2-10:w//2+10]
avg_hsv = np.mean(center_roi, axis=(0,1))
for color_name, (lower, upper) in color_ranges.items():
if lower[0] <= avg_hsv[0] <= upper[0]:
return color_name
return "undefined"
def detect_shape(contour):
"""识别图形形状"""
peri = cv2.arcLength(contour, True)
approx = cv2.approxPolyDP(contour, 0.04 * peri, True)
if len(approx) == 3:
return "triangle"
elif len(approx) == 4:
x, y, w, h = cv2.boundingRect(approx)
aspect_ratio = w / float(h)
return "square" if 0.95 <= aspect_ratio <= 1.05 else "rectangle"
elif len(approx) > 4:
return "circle"
return "undefined"
def main():
cap = cv2.VideoCapture(0)
while True:
ret, frame = cap.read()
if not ret:
break
# 二维码扫描
barcodes = pyzbar.decode(frame)
for barcode in barcodes:
url = barcode.data.decode("utf-8")
webbrowser.open(url)
cv2.putText(frame, "Redirecting...", (30, 50),
cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
# 中心区域处理
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
color_result = detect_color(hsv)
# 形状识别
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (5,5), 0)
edges = cv2.Canny(blurred, 50, 150)
contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
shape_result = "undefined shape"
if contours:
max_contour = max(contours, key=cv2.contourArea)
shape_result = detect_shape(max_contour)
# 绘制中心区域和显示结果
h, w = frame.shape[:2]
cv2.rectangle(frame, (w//2-20, h//2-20),
(w//2+20, h//2+20), (0, 255, 0), 2)
cv2.putText(frame, f"Color: {color_result}", (10, h-60),
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 255), 2)
cv2.putText(frame, f"Shape: {shape_result}", (10, h-30),
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 0, 0), 2)
cv2.imshow("Smart Camera", frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
if __name__ == "__main__":
main()