求助:从复杂图像中提取黄色集装箱方形端面的技术难题
问题描述
从彩色图像中提取黄色集装箱的方形端面时遇到技术难题:
- 目标方形区域与背景色调相近,无明显视觉分界
- 集装箱上方及右侧的树木加剧了识别干扰
尝试通过HSV黄色阈值生成掩码,但无法让边界框准确贴合集装箱端面,原代码及识别情况如下:
原代码
import cv2 as cv im = cv.imread("check1.jpg") # Convert BGR ( not RGB ) to HSV as OpenCV works in BGR, not RGB. hsv = cv.cvtColor(im, cv.COLOR_BGR2HSV) cv.imshow('BGR2HSV__hsv-1',hsv) # set range of yellowish colour, in HSV lower = (8, 0, 0) upper = (78, 255, 255) # Threshold the hSV range to get only yellow colours mask1 = cv.inRange(hsv, lower, upper) #erode the image to get rid of any background dross. mask2 = cv.erode(mask1, kernel=None, iterations=2) (x, y, w, h) = cv.boundingRect(mask2) canvas = cv.cvtColor(mask2, cv.COLOR_GRAY2BGR) final = cv.rectangle(canvas, (x,y), (x+w, y+h), color=(0,0,255), thickness=3) cv.imshow('bounding box-final',final) cv.waitKey(0)
图像情况
- 原始图像:画面左侧是黄色集装箱方形端面,上方及右侧有树木遮挡,背景为浅色调地面/墙面,与集装箱黄色色调接近
- 识别结果图像:掩码误包含部分背景和树木区域,边界框覆盖范围远大于集装箱端面,无法精准定位
优化方案
1. 精细化HSV阈值,动态匹配目标色彩
原HSV范围过于宽泛,导致误识别背景。黄色在HSV中的典型有效范围可通过动态调参工具精准匹配:
import cv2 as cv import numpy as np def nothing(x): pass im = cv.imread("check1.jpg") hsv = cv.cvtColor(im, cv.COLOR_BGR2HSV) cv.namedWindow('Trackbars') cv.createTrackbar('H Lower','Trackbars',20,179,nothing) cv.createTrackbar('H Upper','Trackbars',30,179,nothing) cv.createTrackbar('S Lower','Trackbars',100,255,nothing) cv.createTrackbar('S Upper','Trackbars',255,255,nothing) cv.createTrackbar('V Lower','Trackbars',100,255,nothing) cv.createTrackbar('V Upper','Trackbars',255,255,nothing) while True: h_low = cv.getTrackbarPos('H Lower','Trackbars') h_high = cv.getTrackbarPos('H Upper','Trackbars') s_low = cv.getTrackbarPos('S Lower','Trackbars') s_high = cv.getTrackbarPos('S Upper','Trackbars') v_low = cv.getTrackbarPos('V Lower','Trackbars') v_high = cv.getTrackbarPos('V Upper','Trackbars') lower = np.array([h_low, s_low, v_low]) upper = np.array([h_high, s_high, v_high]) mask = cv.inRange(hsv, lower, upper) cv.imshow('Mask', mask) if cv.waitKey(1) & 0xFF == ord('q'): break cv.destroyAllWindows()
调参完成后,将最终阈值替换到原代码中即可。
2. 形态学操作组合,清除干扰并补全目标区域
原代码仅用腐蚀会缩小目标区域,建议采用开运算+闭运算组合:
# 替换原形态学操作部分 kernel = cv.getStructuringElement(cv.MORPH_RECT, (5,5)) # 开运算:先腐蚀后膨胀,清除背景噪点 mask_open = cv.morphologyEx(mask1, cv.MORPH_OPEN, kernel, iterations=1) # 闭运算:先膨胀后腐蚀,填补集装箱内部缝隙 mask_closed = cv.morphologyEx(mask_open, cv.MORPH_CLOSE, kernel, iterations=2)
3. 轮廓筛选,基于方形特征过滤无效区域
利用集装箱端面的方形特性,通过轮廓的面积、长宽比、多边形近似值筛选目标:
# 替换原boundingRect部分 contours, _ = cv.findContours(mask_closed, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE) canvas = cv.cvtColor(mask_closed, cv.COLOR_GRAY2BGR) for cnt in contours: area = cv.contourArea(cnt) # 过滤过小的噪点轮廓 if area < 5000: continue x, y, w, h = cv.boundingRect(cnt) # 筛选接近方形的轮廓(长宽比0.8-1.2) aspect_ratio = float(w)/h if 0.8 < aspect_ratio < 1.2: # 验证是否为四边形 epsilon = 0.04 * cv.arcLength(cnt, True) approx = cv.approxPolyDP(cnt, epsilon, True) if len(approx) == 4: cv.rectangle(canvas, (x,y), (x+w, y+h), (0,0,255), 3) break cv.imshow('bounding box-final', canvas) cv.waitKey(0)
4. 可选:边缘检测+霍夫直线拟合
若色彩过滤效果仍不理想,可结合边缘检测提取方形边界:
gray = cv.cvtColor(im, cv.COLOR_BGR2GRAY) blur = cv.GaussianBlur(gray, (5,5), 0) edges = cv.Canny(blur, 50, 150) # 霍夫直线检测提取水平/垂直直线 lines = cv.HoughLinesP(edges, 1, np.pi/180, threshold=50, minLineLength=100, maxLineGap=20) # 筛选集装箱的四条边并拟合边界框(需根据实际直线数据调整筛选逻辑)
内容的提问来源于stack exchange,提问作者steve
相关产品推荐
相关产品推荐

