什么是简单边界点(Simple border points)

本文深入探讨了简单边界点的概念及其在图形学领域的应用场景,如领域运算、细化等。通过实例分析,解释了如何判断一个点是否为简单边界点,并详细对比了在4连通和8连通情况下不同连通分量的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

越是概念性的问题,越是令人糊涂。但是,可能大家认为太简单的缘故吧,在网上的资料越是少。

下面Kaiwii就再班门弄斧一回吧……

在图形学中,有一个概念叫做简单边界点(Simple border points)。

在说明这个概念之前,我想首先说说这个概念的应用场景。

比如说,图形学中的领域运算,细化(thinning)等。

接着,我想说说什么叫做连通分量

对于同一个二值图,它的4连通,以及8连通,有可能有不同的连通分量产生。其实,对于这点是很好理解的。

因为,对于4连通来说,对于某一个点A,只要它的东、南、西、北方向上,有点B,就可以说A点与B点相邻。

而对于8连通来说,讨论两个点的邻接情况,就不止4连通的4个方向了,更加包括东南、西北方向等。

理解好什么情况下,两点是邻接的,那么,连通变量就可以这么理解,就是这样子一个点集合,一个点肯定可以通过它的邻接点,或者通过它的它的邻接点的邻接点……一直递归下去找到任何一个点集合中的点。

如果,连通变量这个概念,你都理解好!那么恭喜你,咱们可以转入正题了:什么是简单边界点(Simple border points)

先上概念:

对于S中的一个点P,如果其邻域中属于S的点只有一个与其相邻接的连通分量,则P为S的简单边界点。

对于这个概念,理解也好,不理解也罢。我主要点出两个关键词:只有一个、连通分量。

在开始讲例子之前,就连通分量,我想有两点大家必须要注意的:

1、划分连通域的时候,必须要视p点为无物

2、考虑点是否两点连通的时候必须考虑图像是4连通的还是8连通的


接下来,我就具体例子谈谈我的理解。

分析:

在4连通情况下,

图一中的P点只与连通分量1相连接,所以p是简单边界点

图二中的P点与连通分量1、2都相连接,所以p不是简单边界点

图三中的P点不与任何连通分量相连接,所以p不是简单边界点

在8连通情况下,

图一中的P点与连通分量1、2相连接,所以p不是简单边界点

图二中的P点与连通分量1、2都相连接,所以p不是简单边界点

图三中的P点只与连通分量1相连接,所以p是简单边界点

最后,就8连通的情况,再上一个例子以供大家考虑:


kaiwii出品,欢迎指正!
帮我修复这个自动去除黑边等杂质的代码还是不对,看起来是马赛克的效果,继续完善,import cv2 import numpy as np from scipy.ndimage import binary_dilation def remove_black_borders_with_smart_fill(image, tolerance=15): """ 去除黑边并使用智能纹理合成填充边缘区域 """ # 转换为灰度图 gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) h, w = gray.shape # 创建填充掩码 mask = np.zeros((h + 2, w + 2), dtype=np.uint8) flags = 4 | cv2.FLOODFILL_MASK_ONLY | (255 << 8) seed_points = [(0, 0), (w - 1, 0), (0, h - 1), (w - 1, h - 1)] # 使用副本进行漫水填充 gray_copy = gray.copy() for x, y in seed_points: cv2.floodFill( gray_copy, mask, (x, y), 0, tolerance, tolerance, flags ) fill_mask = mask[1:-1, 1:-1] document_mask = cv2.bitwise_not(fill_mask) # 找到主区域的最小外接矩形 ys, xs = np.where(document_mask > 0) if len(ys) == 0 or len(xs) == 0: return image # 未检测到文档区域,返回原图 top, bottom = ys.min(), ys.max() left, right = xs.min(), xs.max() # 创建结果图像 result = image.copy() # 创建需要填充区域的掩码 fill_region = np.zeros_like(gray, dtype=np.uint8) fill_region[:top, :] = 255 # 上边缘 fill_region[bottom + 1:, :] = 255 # 下边缘 fill_region[:, :left] = 255 # 左边缘 fill_region[:, right + 1:] = 255 # 右边缘 # 创建边界区域(文档边缘附近) border_size = 880 border_region = np.zeros_like(gray, dtype=np.uint8) border_region[top:top + border_size, left:right + 1] = 255 # 上边界 border_region[bottom - border_size + 1:bottom + 1, left:right + 1] = 255 # 下边界 border_region[top:bottom + 1, left:left + border_size] = 255 # 左边界 border_region[top:bottom + 1, right - border_size + 1:right + 1] = 255 # 右边界 # 1. 智能填充算法 # 使用inpaint方法进行纹理合成 filled = cv2.inpaint( result, fill_region, inpaintRadius=3, flags=cv2.INPAINT_TELEA ) # 2. 混合结果 - 保留原始文档区域 # 创建文档区域掩码(扩大一点确保覆盖所有文档内容) document_mask_expanded = binary_dilation(document_mask, structure=np.ones((5, 5)), iterations=3).astype( np.uint8) * 255 document_mask_expanded = cv2.bitwise_and(document_mask_expanded, cv2.bitwise_not(fill_region)) # 组合结果:原始文档区域 + 填充区域 result = np.where( document_mask_expanded[:, :, np.newaxis] > 0, result, filled ) # 3. 使用泊松混合优化边缘 # 创建中心区域掩码(文档区域减去边缘) center_mask = np.zeros_like(gray, dtype=np.uint8) center_mask[top + border_size:bottom - border_size, left + border_size:right - border_size] = 255 center_mask = cv2.bitwise_and(center_mask, document_mask) # 泊松混合 center = result[top:bottom, left:right].copy() blended = cv2.seamlessClone( center, result, center_mask[top:bottom, left:right], ((left + right) // 2, (top + bottom) // 2), cv2.NORMAL_CLONE ) return blended # 使用示例 if __name__ == "__main__": input_image = cv2.imread("zdk/5390004.jpg") if input_image is None: print("无法读取输入图像") else: output_image = remove_black_borders_with_smart_fill(input_image, tolerance=39) cv2.imwrite("output/a.jpg", output_image) print("处理完成,结果已保存")
07-07
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值