基于OpenCV的红外图像箱体轮廓鲁棒检测技术咨询
红外方形箱体鲁棒轮廓检测问题
我需要检测红外相机拍摄图像中箱体及箱内高温物体的轮廓,目前使用classes=2的multiotsu阈值可轻松检测箱内高温物体轮廓,但无法可靠获取箱体轮廓。尝试过Canny边缘检测结合膨胀操作,效果不理想。请问是否有鲁棒的方法检测此类图像中的方形边缘?
关键约束:
- 图像亮度差异大,但箱体始终远冷于内部物体;
- 图像为3通道红外图;
- 可接受近似箱体轮廓(无需完全匹配倾斜边)。
我曾尝试通过蓝通道直方图算法识别箱体上下边界,但仅在特定亮度条件下有效,超出条件则失效,急需更鲁棒的箱体边界检测方法。
附尝试过的代码片段:
代码片段1:Canny边缘+方形轮廓筛选
def is_square(cnt, eps=0.05, aspect_ratio_range=(0.9, 1.1)): # Approximate the contour to reduce the number of points peri = cv2.arcLength(cnt, True) approx = cv2.approxPolyDP(cnt, eps * peri, True) # The contour is considered a square if it has 4 vertices and is convex if len(approx) == 4 and cv2.isContourConvex(approx): _, _, w, h = cv2.boundingRect(approx) aspect_ratio = w / float(h) return aspect_ratio_range[0] <= aspect_ratio <= aspect_ratio_range[1] return False blurred = cv2.GaussianBlur(img, (5, 5), 0) edges = cv2.Canny(blurred_cp, 134,0, apertureSize=3) vertical_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1, 3)) dilated_vertical = cv2.dilate(edges, vertical_kernel, iterations=2) horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 1)) dilated = cv2.dilate(edges, horizontal_kernel, iterations=2) contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) square_contours=[cnt for cnt in contours if is_square(cnt,0.05)] cnt=square_cnt[1] #Here I tried every possible contour that i find x, y, w, h = cv2.boundingRect(max_cnt) cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2) # Draw rectangle plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
代码片段2:蓝通道直方图边界检测
r,g,b= cv2.split(im) b=cv2.bitwise_not(b) h=cv2.calcHist([b],[0],None,[256],[0,256]) h=h[15:] # Calculate the indices of the maxima of the histogram indices = argrelextrema(h, np.greater) # Get the values of the maxima of the histogram maxima = h[indices] # Find the indices of the 2 highest maxima top_2_indices = maxima.argsort()[-2:][::-1] # These are the VALUES of h at indices maxima = h[indices] # These are the indices of the highest values in the maxima array top_2_indices = maxima.argsort()[-2:][::-1] # These are the indices in h of the two highest peaks just found highest_values = indices[0][top_2_indices] # These are the same values, still in h, but sorted in ascending order, so the left peak appears first, and then the right peak. highest_values_sorted=sorted(highest_values) values_h_at_peaks= h[highest_values_sorted] small_peak_value=min(values_h_at_peaks)[0] _, tresh = cv2.threshold(b, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) # thresholding tresh_padded = np.pad(tresh, ((0, 2), (0, 0)), 'constant') row_sums = np.sum(tresh_padded, axis=1) window_size = 3 window_sums = np.convolve(row_sums, np.ones(window_size), 'valid') peaks, properties = find_peaks(window_sums, height=small_peak_value/2,distance=30,prominence=0.5) peak_heights = properties['peak_heights'] top_2_indices = peak_heights.argsort()[-2:][::-1] # Get the 3 best peaks best_peaks = peaks[top_2_indices] cv2.line(im, (0, best_peaks[1]), (im.shape[1], best_peaks[1]), (0, 255, 0), 2) cv2.line(im, (0, best_peaks[0]), (im.shape[1], best_peaks[0]), (0, 255, 0), 2)
同时提供了原始图像、检测到的轮廓、Canny边缘图、期望边界框及多组不同亮度的示例图像。
内容的提问来源于stack exchange,提问作者user15233037
相关产品推荐
相关产品推荐

