You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何定位并测量图像中的长条形结构?求第三步后的优化方案

图像长条形结构检测:旋转后的后续处理方案

你已经完成图像二值化、轮廓检测和水平旋转,接下来可通过以下步骤精准提取目标长条形结构:

步骤1:裁剪旋转图像,去除无效黑边

旋转后图像周围会产生大量黑边,裁剪到目标物体的 bounding box 可减少干扰,聚焦有效区域:

# 获取旋转后轮廓的边界框
x2, y2, w2, h2 = cv2.boundingRect(cnt2)
# 裁剪旋转后的二值图
cropped_binary = binary_rotated[y2:y2+h2, x2:x2+w2]

步骤2:形态学操作,强化长条形特征

使用开运算(先腐蚀再膨胀)去除小噪点,同时保留长条形的连续结构;若目标结构较细,可搭配水平方向结构元素做膨胀,突出横向特征:

# 创建适配长条形的水平结构元素
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (15, 3))
# 开运算去噪并强化结构
morph_img = cv2.morphologyEx(cropped_binary, cv2.MORPH_OPEN, kernel)

步骤3:二次轮廓检测+筛选长条形轮廓

重新检测轮廓后,通过宽高比(水平旋转后长条形宽远大于高)和面积阈值筛选目标结构:

contours3, hierarchy3 = cv2.findContours(morph_img.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
target_contours = []
for cnt in contours3:
    area = cv2.contourArea(cnt)
    x, y, w, h = cv2.boundingRect(cnt)
    # 根据实际场景调整宽高比和面积阈值
    if w / h > 5 and area > 100:
        target_contours.append(cnt)

步骤4:绘制并可视化结果

将筛选出的长条形轮廓绘制到原图和处理后的图像上:

# 在裁剪图上绘制目标轮廓
cv2.drawContours(cropped_binary, target_contours, -1, (0, 255, 0), 2)
# 将裁剪结果放回旋转图(用于整体可视化)
binary_rotated[y2:y2+h2, x2:x2+w2] = cropped_binary
# 把轮廓坐标映射回原图并绘制
for cnt in target_contours:
    cnt_rotated = cnt + np.array([x2, y2])
    cnt_original = cv2.transform(np.array([cnt_rotated]), rotate_matrix)[0]
    cv2.drawContours(img00, [cnt_original.astype(np.int32)], -1, (0, 0, 255), 2)

修改后的完整代码

import cv2
import numpy as np
import math

iterations = 7
a = 0  # 替换为你的实际变量值
img00 = cv2.imread('./camera1'+str(a)+'.jpg')
gray00 = cv2.cvtColor(img00, cv2.COLOR_BGR2GRAY)

median_blur1 = cv2.medianBlur(gray00, iterations) # 中值滤波去噪
ret1, thresh1 = cv2.threshold(median_blur1,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU) # Otsu二值化

# 检测外部轮廓
contours1, hierarchy1 = cv2.findContours(thresh1.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
if len(contours1) == 0:
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    exit()

# 获取最大轮廓
c1 = max(contours1, key = cv2.contourArea)

height, width = img00.shape[:2]
center = (width//2, height//2)  # 用整数避免浮点问题
rect1 = cv2.minAreaRect(c1)
print(rect1[2])

# 旋转图像到水平
rotate_matrix = cv2.getRotationMatrix2D(center=center, angle=rect1[2], scale=1)
binary_rotated = cv2.warpAffine(src=thresh1, M=rotate_matrix, dsize=(width, height))

# 检测旋转后的轮廓
contours2, hierarchy2 = cv2.findContours(binary_rotated.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnt2 = contours2[0]

# 裁剪旋转图像,去除黑边
x2, y2, w2, h2 = cv2.boundingRect(cnt2)
cropped_binary = binary_rotated[y2:y2+h2, x2:x2+w2]

# 形态学操作强化长条形结构
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (15, 3))
morph_img = cv2.morphologyEx(cropped_binary, cv2.MORPH_OPEN, kernel)

# 筛选长条形轮廓
contours3, hierarchy3 = cv2.findContours(morph_img.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
target_contours = []
for cnt in contours3:
    area = cv2.contourArea(cnt)
    x, y, w, h = cv2.boundingRect(cnt)
    # 根据实际情况调整阈值
    if (w / h > 5 or h / w > 5) and area > 100:
        target_contours.append(cnt)

# 绘制结果
cv2.drawContours(cropped_binary, target_contours, -1, (0, 255, 0), 2)
binary_rotated[y2:y2+h2, x2:x2+w2] = cropped_binary

# 映射回原图并绘制
for cnt in target_contours:
    cnt_rotated = cnt + np.array([x2, y2])
    cnt_original = cv2.transform(np.array([cnt_rotated]), rotate_matrix)[0]
    cv2.drawContours(img00, [cnt_original.astype(np.int32)], -1, (0, 0, 255), 2)

cv2.imshow('Original Image with Target', img00)
cv2.imshow('Rotated & Processed', binary_rotated)
cv2.waitKey(0)
cv2.destroyAllWindows()

内容的提问来源于stack exchange,提问作者Kimwaga Makono

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 09:55:25