opencv-GrabCut
解决pycharm使用import cv2后没有代码提示
备注: 以miniconda为例,找到cv2的文件夹:
mininconda安装路径 + ‘envs\api\Lib\site-packages\cv2’
在 pycharm -> python Interpreter -> show all,找到对应的编译器右键 -> show interoreter paths -> 点击‘+’号 -> 输入 cv2 路径后点击 ‘ok’ 即可或者直接点击
opencv 算法库
opencv所提供的GrabCut算法包含两种模式(RECT/MASK)
RECT模式:
bgdmodel = np.zeros((1, 65), np.float64)
fgdmodel = np.zeros((1, 65), np.float64)
cv2.grabCut(img, mask, rect, bgdModel, fgdModel, iterCount, cv.GC_INIT_WITH_RECT)
MASK模式:
cv2.grabCut(img, mask, None, bgdModel, fgdModel, iterCount, cv.GC_INIT_WITH_RECT)
参数说明:
- img: 待分割的图像,必须是8位3通道的形式,分割过程中不会被修改
- mask:分割过程中修改的对象,分割的范围根据rect指定
- rect:限定进行分割的图像范围,只有矩形框内的图像部分才会进行分割流程。只有在RECT模式下才会生效
- bgdModel / fgdModel:单通道浮点型图像,行数为1,列数为13*5
- iterCount:迭代次数(大于0)
- mode:
- RECT模式:
- GC_INIT_WITH_RECT(=0),用矩形窗初始化GrabCut;
- RECT模式下所选定的矩形框内的所有像素都会重置为不确定背景或者不确定前景,ROI外部为“确定性背景”
- MASK模式:
- GC_INIT_WITH_MASK(=1),用掩码图像初始化GrabCut;
- MASK模式下对mask中不确定的像素点进行图像分割
通常使用grabcut算法会与鼠标交互联合使用,以下简单介绍:
opencv-setMouseCallBack
cv2.namedWindow('img')
cv2.setMouseCallback('img', onmouse)
cv2.imshow('img', img)
需要定义鼠标回调函数:
def on_mouse(event, x, y, flags, param):
if event == cv.EVENT_LBUTTONDOWN:
...
elif event == cv.EVENT_MOUSEMOVE:
...
elif event == cv.EVENT_LBUTTONUP:
...
需要注意的是鼠标交互会直接在原始输入的img上进行修改,也就是onmouse中处理的基本上都为全局变量。如果不希望对原始图像进行修改,可以通过以下方式进行传入。
img_mouse = img.copy()
param = []
param.append(img_mouse)
'''
后续将param参数传入到on_mouse中即可对img_mouse进行修改
'''
img_mouse = self.param[0].copy()
if event == cv2.EVENT_LBUTTONDOWN:
point_down = (x, y)
elif event == cv2.EVENT_MOUSEMOVE and (flags & cv2.EVENT_FLAG_LBUTTON):
# 显示的img_mouse 不会有拖动痕迹, 只会实时显示一个框
cv2.rectangle(self.param[0], point_down, (x, y), (0, 255, 0), thickness=2)
cv2.imshow('ROI', self.param[0])
# 显示的img_mouse 会有拖动显示拖动痕迹, 只会实时显示一个框
cv2.rectangle(self.param[0], point_down, (x, y), (0, 255, 0), thickness=2)
cv2.imshow('ROI', self.param[0])
elif event == cv2.EVENT_LBUTTONUP:
point_up = (x, y)
cv2.rectangle(img_mouse, point_down, point_up, (0, 0, 255), thickness=2)
cv2.imshow('ROI', img_mouse)
self.xy.append([point_down, point_up])
print(point_down)
print(point_up)
self.seg = True