毕设随记-3-实现图像子块的分割

首先的想法是,基于RGB来分割。首先写一个函数,读取原图片,当鼠标点击对应位置时返回其坐标(X,Y)以及对应的RGB值,便于后续作为阈值的设置。

函数实现如下:

ini 复制代码
# 定义鼠标点击事件的回调函数
def on_click(event):
    # 当鼠标左键被按下
    if event.button == 1:  # 1 代表鼠标左键
        # 打印点击位置的坐标(注意:这里的坐标是以图像的左上角为原点的)
        # 获取点击位置的坐标
        x = int(event.xdata)
        y = int(event.ydata)
         # 获取点击位置的RGB值
        rgb = image[y, x]
        # 打印点击位置的坐标和RGB值
        print(f"X: {x}, Y: {y}, RGB: {rgb}")
# 读取图像
image = cv2.imread('mini1.jpg')  
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)  # 将图像从BGR转换为RGB

# 显示图像
fig, ax = plt.subplots()
ax.imshow(image)

# 连接事件回调函数
fig.canvas.mpl_connect('button_press_event', on_click)

plt.show()

但实际上,RGB是不利于实现分割的,HSV空间才是更为合适的那个。为此我改写了上述函数,并对背景部分,以及黑色杂质部分进行hsv值的读取,并依次设定范围

改写后的函数如下:

ini 复制代码
def on_click(event):
    # 当鼠标左键被按下
    if event.button == 1:  # 1 代表鼠标左键
        # 打印点击位置的坐标(注意:这里的坐标是以图像的左上角为原点的)
        # 获取点击位置的坐标
        x = int(event.xdata)
        y = int(event.ydata)
        # 获取点击位置的RGB值
        rgb = image[y, x]
        # 打印点击位置的坐标和RGB值
        # print(f"X: {x}, Y: {y}, RGB: {rgb}")

        # 将RGB值转换为HSV值
        hsv = colorsys.rgb_to_hsv(rgb[0] / 255, rgb[1] / 255, rgb[2] / 255)
        # 调整H、S、V值到0~180、0~255、0~255范围
        # 在OpenCV中,HSV的取值范围有时会稍微不同,这取决于实现。通常,H在0到179之间,而S和V在0到255之间。
        h = int(hsv[0] * 180)
        s = int(hsv[1] * 255)
        v = int(hsv[2] * 255)
        # 打印点击位置的坐标和HSV值
        print(f"X: {x}, Y: {y}, HSV: ({h}, {s}, {v})")


# 读取图像
image = cv2.imread('mini1.jpg')
image = cv2.pyrMeanShiftFiltering(image, 10, 20)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)  # 将图像从BGR转换为RGB

# 显示图像
fig, ax = plt.subplots()
ax.imshow(image)

# 连接事件回调函数
fig.canvas.mpl_connect('button_press_event', on_click)

plt.show()

实现初步分割后,效果还是不错的。进一步的,就是要对像素点大小等进行一定的限制,比如,若黑色杂质点的hsv值满足初步分割的条件会导致计数时发生错检,但往往杂质点的所占像素范围是比较小的。因此,可以根据图像中的非白色点的所占空间以进一步去除黑色杂点。

那么最简单的思想当然是滑动窗口法了。同样的,也需要想怎样才能在去除黑色杂质时不误去除铜屑部分。---直接进行形态学处理可能也行?先试试开运算


**开运算:先腐蚀再膨胀 ** dst = cv2.morphologyEx(src, cv2.MORPH_OPEN, kernel)--

  • 针对kernel,可以使用cv2.getStructuringElement(cv2.MORPH_RECT, kernel_size))指定核的形状,常用的有矩形结构和椭圆形结构(我感觉用起来差异不大)

图1是预处理后的原图,图2、3分别是使用椭圆形结构和矩形结构的开运算后的图像。


直方图均衡化用于图像增强:

左图是经直方图均衡化后再结合腐蚀与膨胀操作后的图,右图是直方图均衡化后的图。明显可见,细小的点(杂质小点)被去除了,相对"大块头"的铜屑部分得以保留。


进一步,增强后要对原图像中的闭合图像个数进行计数

对一个子图能实现边框检测+计数啦,今天就先点到为止,明天继续考虑优化以及其他可能算法的对比。

相关推荐
khalil10203 分钟前
代码随想录算法训练营Day-50 图论02 | 99.岛屿数量-深搜、99.岛屿数量-广搜 、100.岛屿的最大面积
数据结构·c++·算法·leetcode·深度优先·图论
Brilliantwxx4 分钟前
【C++】模版进阶(特化+分离编译+非类型模版参数)
开发语言·数据结构·c++·算法
Black蜡笔小新4 分钟前
自动化AI算法训练服务器DLTM企业级AI模型工作站构筑企业AI自主可控新模式
人工智能·算法·自动化
bnmoel4 分钟前
数据结构深度剖析链表全集:结构实现、分类与底层原理全解析
c语言·数据结构·算法·链表·双向链表
童先生15 分钟前
华为云、阿里云、AWS签名机制详解! AK/SK + HMAC-SHA256 签名鉴权!
算法·阿里云·华为云·云计算
承渊政道16 分钟前
【贪心算法】(经典实战应用解析(二):最⻓递增⼦序列、递增的三元⼦序列、最⻓连续递增序列、买卖股票的最佳时机、买卖股票的最佳时机II)
数据结构·c++·学习·算法·leetcode·贪心算法·哈希算法
li星野19 分钟前
动态规划十题通关:从爬楼梯到编辑距离(Python + C++)
c++·python·学习·算法·动态规划
栈溢出了22 分钟前
GAT(Graph Attention Network)学习笔记
人工智能·深度学习·算法·机器学习
Tutankaaa22 分钟前
学校知识竞赛怎么组织?从班级到年级的进阶方案
经验分享·学习·算法·职场和发展
qcx2323 分钟前
混合检索+重排序:当前 RAG 精度提升最成熟的工程路径
算法·ai·llm·agent·rag·agentic