求不规则形状内像素点

原文地址:http://www.blogbus.com/linxinboy-logs/261546856.html

上次写了个求凸状的图形内像素点,本来以为求任意形状 包括凹状的图形内的像素点比较麻烦。 后来仔细想了一下,其实很简单。

比如这张图:

如何求黑色线条内部的点呢?

很简单。

首先 我们定义一个节点类

 public class PointInt
{
	public var x:int;

	public var y:int;

	public var left:Boolean = false;;

	public var right:Boolean = false;;

	public var up:Boolean = false;;

	public var down:Boolean = false;;

	public var block:Boolean = false;

	public function get fullConnected():Boolean
	{
		return left && right && up && down;
	}

	public function PointInt(x:int = 0, y:int = 0, block:Boolean = false)
	{
		this.x = x;
		this.y = y;
		this.block = block;
	}
}

 其中 x y 为节点位置 上下左右 分别标记当前节点是否  有找到它上下左右的节点 比如 (0,0)节点 如果找到右边的节点(1,0)则(0,0)的right标记为true, (1,0)的left标记为true. block表示是否是黑色线条区域,即边界。

然后 我们找到边界区域的最大最小 x, y值 minX, maxX minY maxY

我们做一个一个矩形 左上点为 (minX - 1, minY - 1) 右上点为 (maxX + 2, maxY + 2)

如图

所以 此块区域内的第一行节点 肯定是处于线条外部(如果 min http:// X - 1

我们把第一行的节点全部push到一个list中去。

然后遍历这个list 中的节点 如果它不是fullConnected 即它没有找到它上下左右的所有节点 则寻找它没有找到的节点 , push进list

直到list中的所有节点都为fullConnected.

这个过程可以如下看到: 点击以后开始运行

http://files.cnblogs.com/v-miclin/PtInShapeTest.swf

你可一看到 边缘外部像素 好像注水一样逐渐注入 最后整个矩形非外部的像素即为边缘内部像素。

最后的结果:

源码: 不给。

### 使用Python从非矩形或自定义形状区域内提取图像像素 为了实现从非矩形或自定义形状区域内提取图像像素,在Python中有多种方法可以完成此任务。常用的技术涉及创建掩模(mask),该掩模定义哪些像素属于感兴趣的区域,随后利用这个掩模来筛选原始图像中的相应像素。 #### 方法一:使用PIL库与NumPy结合 当目标是从特定形状内获取像素时,可以通过`Pillow`库绘制所需的形状作为掩模,并借助于`NumPy`数组操作来进行高效的像素选取。下面是一个简单的例子展示如何做到这一: ```python from PIL import Image, ImageDraw import numpy as np # 创建一个新的白色背景图片 img = Image.new('RGB', (500, 500), color = 'white') draw = ImageDraw.Draw(img) # 定义一个多边形轮廓列表 polygon_points = [(100, 150), (300, 200), (400, 350), (250, 400)] # 在新图层上画出多边形并填充黑色表示选区 mask_img = Image.new('L', img.size, 0) ImageDraw.Draw(mask_img).polygon(polygon_points, fill=255) # 将原图转换成numpy array形式以便后续处理 np_img = np.array(img) # 应用掩码到原图数据上得到裁剪后的结果 masked_np_img = cv2.bitwise_and(np_img, np_img, mask=np.array(mask_img)) # 转回image对象显示最终效果 result_image = Image.fromarray(masked_np_img) result_image.show() ``` 这段代码先建立了一个新的空白图像文件,接着在其副本上描绘出了想要的任意形状——这里是以四个顶构成的一个四边形为例;之后再把这个图形转为二值化的灰度模式(`'L'`)下的遮罩图像,其中被标记出来的部分即为我们所关心的对象所在位置。最后一步则是运用布尔逻辑运算符将这些信息施加给源图像的数据集,从而实现了只保留选定范围内的色彩信息的效果[^1]。 #### 方法二:基于OpenCV的手动选择ROI 另一种方式是采用交互式的手段让用户自己去圈定感兴趣的部分,这主要依赖于`cv2.setMouseCallback()`函数监听鼠标的击事件,进而动态调整覆盖在视频帧上的透明蒙版大小直至满意为止。这种方式非常适合那些难以提前预知确切几何特征的情况。 ```python import cv2 def draw_circle(event,x,y,flags,param): global ix,iy,drawing,mode if event == cv2.EVENT_LBUTTONDOWN: drawing = True ix,iy = x,y elif event == cv2.EVENT_MOUSEMOVE: if drawing == True: if mode == True: cv2.circle(img,(x,y),5,(0,0,255),-1) elif event == cv2.EVENT_LBUTTONUP: drawing = False if mode == True: cv2.circle(img,(x,y),5,(0,0,255),-1) drawing = False # true if mouse is pressed ix,iy = -1,-1 img = np.zeros((512,512,3), np.uint8) cv2.namedWindow('image') cv2.setMouseCallback('image',draw_circle) while(1): cv2.imshow('image',img) k = cv2.waitKey(1) & 0xFF if k == ord('m'): mode = not mode elif k == 27: break cv2.destroyAllWindows() # 提取由用户绘制的所有红色圆形组成的区域作为ROI gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) _, thresh = cv2.threshold(gray, 1, 255, cv2.THRESH_BINARY) contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2:] roi_mask = np.zeros_like(gray) cv2.drawContours(roi_mask, contours, -1, 255, thickness=cv2.FILLED) # 对实际输入图像应用上述获得的ROI Mask... input_image = ... # 加载待处理的真实图像路径 output = cv2.bitwise_and(input_image,input_image,mask = roi_mask) ``` 在这个脚本里,通过设置回调机制允许使用者自由地在窗口内部勾勒闭合曲线,每当松开按钮后就会自动形成封闭的空间供下一步骤调用。一旦完成了整个过程,则可依据之前累积下来的轨迹构建起完整的边界描述并向外扩展至完全包围住所有已标注过的斑群组,以此为基础建立起精确匹配的选择条件[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值