如何提升边缘检测精度,准确统计传送带不同尺寸岩石数量
岩石尺寸统计代码优化问题
问题描述
我需要编写代码准确统计指定尺寸范围(30-40mm、40-50mm、50-60mm、60mm+)的岩石数量。目前已编写代码但效果不佳,执行步骤如下:
- 缩小图像尺寸
- 转换为灰度图
- 高斯模糊处理
- 阈值处理去除纯暗区域
- 使用
cv2.bitwise_and()将模糊图像与阈值图像结合 - 查找并绘制面积>100的轮廓
核心问题:无法获取岩石的闭合轮廓,导致无法计算面积、长短轴以确定岩石尺寸。
案例展示
案例1
- 原始图像
- 绘制轮廓后的输出图像
- 检测到的物体总数=162
案例2
- 原始图像
- 绘制轮廓后的输出图像
- 检测到的物体总数=149
求助:如何提升代码的准确性?
当前代码
import cv2 import numpy as np import csv # 读取图像 img = cv2.imread("Images/24.jpg") # 图像缩放比例 scale_percent = 75 # 计算缩放后的尺寸(原代码此处错误,img.shape[2]为通道数,应改为shape[1]) width = int(img.shape[1] * scale_percent / 100) height = int(img.shape[0] * scale_percent / 100) # 目标尺寸 dsize = (width, height) # 缩放图像 original = cv2.resize(img, dsize) cv2.imshow("Original", original) cv2.waitKey(0) # 转换为灰度图 gray = cv2.cvtColor(original, cv2.COLOR_BGR2GRAY) # 高斯模糊去噪 blur = cv2.GaussianBlur(gray, (5, 5), 0) # 阈值分割:像素值小于50设为255(前景),大于等于50设为0(背景) thresh = cv2.threshold(blur, 50, 255, cv2.THRESH_BINARY)[2] cv2.imshow("thresh", thresh) cv2.waitKey(0) # 去除图像噪声 # 定义核大小 # kernel = np.ones((5,5),np.uint8) # mask = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel) # mask = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel) mask = cv2.dilate(thresh, None, iterations=1) cv2.imshow("Noise Removal", mask) cv2.waitKey(0) # 结合模糊图像与掩码 segmented_img = cv2.bitwise_and(blur, blur, mask=mask) cv2.imshow("segmented", segmented_img) cv2.waitKey(0) # 边缘检测 edged_2 = cv2.Canny(segmented_img, 120, 180) cv2.imshow("Canny on segmented image", edged_2) cv2.waitKey(0) # 查找轮廓 cnts = cv2.findContours(edged_2.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) cnts = cnts[0] output = original.copy() objects_number = 0 major_axis = 0 minor_axis = 0 results = [] for c in cnts: area = cv2.contourArea(c) print("轮廓面积:", area) if area >= 100: # 拟合椭圆(原代码错误,ellipse[2]为旋转角度,长短轴存于ellipse[1]) ellipse = cv2.fitEllipse(c) major_axis = round(max(ellipse[1]), 2) minor_axis = round(min(ellipse[1]), 2) results.append([area, major_axis, minor_axis]) objects_number += 1 # 绘制轮廓 cv2.drawContours(output, [c], -1, (240, 0, 159), 3) print("检测到的物体总数 =", objects_number) # 写入结果到CSV(原代码错误,writers应为writerow) with open('results.csv', 'w', newline='') as file: writer = csv.writer(file) # 写入表头 writer.writerow(['轮廓面积', '长轴', '短轴']) # 写入结果 for row in results: writer.writerow(row) print("物体总数 =", objects_number) cv2.imshow("Contours", output) cv2.waitKey(0) cv2.destroyAllWindows()
内容的提问来源于stack exchange,提问作者sangams314
相关产品推荐
相关产品推荐

