### 使用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]。