首页 新闻 会员 周边 捐助

图像特征提取

0
悬赏园豆:30 [已解决问题] 解决于 2024-12-06 14:16

这种图像怎么提取中间的黑色线条啊,,求救

仟树的主页 仟树 | 初学一级 | 园豆:127
提问于:2024-12-04 22:39
< >
分享
最佳答案
1

先用灰度平均值二值化,然后在图片上纵向找出每一行的分割点使图片两边的差异最大,然后把它们连起来成为一条直线

import cv2
import numpy as np

# 读取图像并转换为灰度图
image = cv2.imread('1.jpg', cv2.IMREAD_GRAYSCALE)

# 计算灰度图的平均值
mean_gray_value = np.mean(image)

# 使用平均灰度值作为阈值进行二值化
_, binary = cv2.threshold(image, mean_gray_value, 255, cv2.THRESH_BINARY)

# 获取图像的高度和宽度
height, width = binary.shape

# 存储分割点的坐标
split_points = []

# 定义一个函数来计算给定分割点的左右侧差异
def calculate_variance_difference(row, x):
    left_side = row[:x]
    right_side = row[x:]
    if len(left_side) == 0 or len(right_side) == 0:
        return 0
    variance_left = np.count_nonzero(left_side)/len(left_side)
    variance_right = np.count_nonzero(right_side)/len(right_side)
    return abs(variance_left - variance_right)

# 遍历每一行,寻找最佳分割点
for y in range(height):
    row = binary[y, :]
    best_x = None
    max_diff = 0
    for x in range(width//2-100, width//2+100): ### 根据实际情况调整范围!!
        diff = calculate_variance_difference(row, x)
        if diff > max_diff:
            max_diff = diff
            best_x = x
    if best_x is not None:
        split_points.append((best_x, y))

# 将分割点转换为NumPy数组
split_points_np = np.array(split_points)

# 拟合直线
if len(split_points_np) >= 2:  # 至少需要两个点才能拟合一条直线
    [vx, vy, x0, y0] = cv2.fitLine(split_points_np, cv2.DIST_L2, 0, 0.01, 0.01)
    lefty = int((-x0*vy/vx) + y0)
    righty = int(((width-x0)*vy/vx) + y0)
else:
    print("无法拟合直线,因为分割点不足")
    exit()

# 绘制直线
color_image = cv2.cvtColor(binary, cv2.COLOR_GRAY2BGR)  # 转换为彩色以便绘制不同颜色的线
cv2.line(color_image, (0, lefty), (width-1, righty), (0, 255, 0), 2)

# 显示结果
cv2.imshow('Image with Split Line', color_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

# 如果需要保存分割后的图像
cv2.imwrite('image_with_split_line.jpg', color_image)
收获园豆:30
www378660084 | 小虾三级 |园豆:1325 | 2024-12-05 13:05

好的,谢谢,虽然拟合的精度在图像的某些地方效果不是那么好

仟树 | 园豆:127 (初学一级) | 2024-12-05 15:06

@仟树: 这个方法找到的点,一般都在分割线的一边,因为分割线是黑色的有宽度,分割线会被划分到灰度较大的那一边,把点往灰度较大的那边偏移一点,然后再拟合效果会好一些.

www378660084 | 园豆:1325 (小虾三级) | 2024-12-05 15:26

@www378660084: 好的,谢谢

仟树 | 园豆:127 (初学一级) | 2024-12-05 15:29
其他回答(2)
0

灰度转换、二值化、边界获取(opencv有边界获取函数)

彼时今日 | 园豆:570 (小虾三级) | 2024-12-05 08:52

二值化噪声太多,滤波也没用

支持(1) 反对(0) 仟树 | 园豆:127 (初学一级) | 2024-12-05 10:07
0

如果总是这种图像,直接一个像素从左到右遍历取个阈值就出来了

寂静的羽夏 | 园豆:2261 (老鸟四级) | 2024-12-05 09:28

是直接设定阈值二值化的意思吗,这样好像也不行

支持(0) 反对(0) 仟树 | 园豆:127 (初学一级) | 2024-12-05 10:10
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册