计算机视觉(四) 旧城等待, 2022-06-02 00:58 257阅读 0赞 Grabcut [Grabcut算法详解][Grabcut] http://blog.csdn.net/zouxy09/article/details/8534954 原理: 首先用矩形将要选择的前景区域选定,其中前景区域应该完全包含在矩形框当中。然后算法进行迭代式分割,知道达到效果最佳。但是有时分割结果不好,例如前景当成背景,背景当成前景。测试需要用户修改。用户只需要在非前景区域用鼠标划一下即可。 首先,输入矩形框,矩形框外部区域都是背景。内部一定包含前景。电脑对输入图像进行初始化,标记前景和背景的像素。使用高斯混合模型(GMM)对前景和背景建模。根据输入,GMM会学习并创建新的像素分布。对未知的像素(前景或背景不确定),根据他们与已知的分类像素关系进行分类。(类似聚类操作)这样会根据像素的分布创建一幅图,图中节点是像素。除了像素点是节点以外,还有Source\_node和Sink\_node两个节点。所有的前景图像斗鱼Source\_node相连。背景与Sink\_node相连。像素是否连接到Source\_node/end\_node依赖于权值,这个权值由像素属于同一类,也就是前景或者背景的概率来决定。如果像素的颜色有很大区别,那么他们之间的权重就很小。使用mincut算法对图像进行分割。它会根据最小代价方程对图像分成source\_node和sink\_node。代价方程是指裁剪所有边上权重的和。裁剪完成后,所有连接到source\_node的判定为前景,sink\_node上的为背景。继续此过程,直到分类收敛。 def grabCut(img, mask, rect, bgdModel, fgdModel, iterCount, mode=None): # real signature unknown; restored from __doc__ """ grabCut(img, mask, rect, bgdModel, fgdModel, iterCount[, mode]) -> mask, bgdModel, fgdModel """ pass cv2.grabCut()函数参数 * img 输入图像,图像的类型必须为:CV\_8UC3 * **mask 掩模图像,确定**前景**区域,**背景**区域,不确定区域**,可以设置为cv2.GC\_BGD,cv2.GC\_FGD,cv2.GC\_PR\_BGD,cv2.GC\_PR\_FGD,也可以输入0,1,2,3它的大小和image一样,但是它的格式为CV\_8UC1,只能是单通道的,grabcut算法的结果就保存在该图像中。 mask图像的值只能为下面下面4个值(PR,probably表示可能的):计算完成后mask里面值为0到3,其中0表示背景,1表示前景,2表示可能是背景,3表示可能是前景 ,代码中将0和2合并为背景 1和3合并为前景 GC\_BGD = 0, //背景 GC\_FGD = 1, //前景 GC\_PR\_BGD = 2, //可能背景 GC\_PR\_FGD = 3 //可能前景 代码中将0和2合并为背景 1和3合并为前景 根据rectangle生成的mask图像规则为:四边形外面的部分一定是背景,所以在mask图中对应的像素值为GC\_BGD,而四边形内部的的值可能为前景,所以对应的像素值为GC\_PR\_FGD。 * rect 前景的矩形,格式为(x,y,w,h),分别为左上角坐标和宽度,高度 * **bdgModel, fgdModel)****临时矩阵变量**,只需要创建两个大小为(1,65)np.float64的数组。 * bgdModel(background背景)——背景模型,如果为null,函数内部会自动创建一个bgdModel;bgdModel必须是单通道浮点型(CV\_32FC1)图像,且**行数只能为1,列数只能为13x5**; fgdModel(foreground前景——前景模型,如果为null,函数内部会自动创建一个fgdModel;fgdModel必须是**单通道浮点型**(CV\_32FC1)图像,且**行数只能为1,列数只能为13x5**; * **iterCount 迭代次数,迭代越多,效果越好,但划时间也越长。** * mode cv2.GC\_INIT\_WITH\_RECT 或 cv2.GC\_INIT\_WITH\_MASK,使用矩阵模式还是掩模模式。 * mode——用于指示grabCut函数进行什么操作,可选的值有: GC\_INIT\_WITH\_RECT(=0),用矩形窗初始化GrabCut; GC\_INIT\_WITH\_MASK(=1),用掩码图像初始化GrabCut; GC\_EVAL(=2),执行分割。 * 参数为GC\_INIT\_WITH\_MASK,这时第三个参数rectangle没有使用,我们必须在调用grabcut函数之前,手工设置mask图像 1、自定义(自设区域选定) 静态图像: import numpy as np from cv2 import * from matplotlib import pyplot as plt filename="D:/temp/6.jpg" img=imread(filename) mask=np.zeros(img.shape[:2],np.uint8) bgdmodel=np.zeros((1,65),np.float64) fgdmodel=np.zeros((1,65),np.float64) #img.shape[0],img.shape[1],表图像的高度和宽度 rect=(2,2,img.shape[0]-1,img.shape[1]-1) grabCut(img,mask,rect,bgdmodel,fgdmodel,6,GC_INIT_WITH_RECT) mask2=np.where((mask==2)|(mask==0),0,1).astype('uint8') img=img*mask2[:,:,np.newaxis] plt.subplot(121),plt.imshow(img) plt.title('grabcut'),plt.xticks([]),plt.yticks([]) plt.subplot(122),plt.imshow(cvtColor(imread(filename),COLOR_BGR2RGB)) plt.title('original'),plt.xticks([]),plt.yticks([]) plt.show() C++代码参考: http://blog.csdn.net/l1l2l3q1q2q3/article/details/51181975 http://blog.csdn.net/wangyaninglm/article/details/50074613 http://blog.csdn.net/zxc024000/article/details/51243629 http://blog.csdn.net/roslei/article/details/52221975 (Java)http://blog.csdn.net/huohuxingxing1987/article/details/13278375 摄像(动态): import numpy as np from cv2 import * from matplotlib import pyplot as plt videocapture=VideoCapture(0) ret,img=videocapture.read() while ret: image = img mask=np.zeros(img.shape[:2],np.uint8) bgdmodel=np.zeros((1,65),np.float64) fgdmodel=np.zeros((1,65),np.float64) rect=(1,1,image.shape[0],image.shape[1]) grabCut(img,mask,rect,bgdmodel,fgdmodel,2,GC_INIT_WITH_RECT) mask2=np.where((mask==2)|(mask==0),0,1).astype('uint8') img=img*mask2[:,:,np.newaxis] imshow('Grabcut',img) imshow('Image',image) waitKey(1) ret, img = videocapture.read() destroyAllWindows() 运行非常慢。 2、交互模式 参考:http://blog.topspeedsnail.com/archives/2080 http://blog.csdn.net/tengfei461807914/article/details/62438959 [鼠标画笔 setMouseCallback()][setMouseCallback]:http://blog.csdn.net/qton\_csdn/article/details/70193884 创建一个鼠标回调函数,在指定事件发生时执行。 使用如下代码查看鼠标事件: import cv2 events=[i for i in dir(cv2)if 'EVENT' in i] print events 事件:\['EVENT\_FLAG\_ALTKEY', 'EVENT\_FLAG\_CTRLKEY', 'EVENT\_FLAG\_LBUTTON', 'EVENT\_FLAG\_MBUTTON', 'EVENT\_FLAG\_RBUTTON', 'EVENT\_FLAG\_SHIFTKEY', 'EVENT\_LBUTTONDBLCLK', 'EVENT\_LBUTTONDOWN', 'EVENT\_LBUTTONUP', 'EVENT\_MBUTTONDBLCLK', 'EVENT\_MBUTTONDOWN', 'EVENT\_MBUTTONUP', 'EVENT\_MOUSEHWHEEL', 'EVENT\_MOUSEMOVE', 'EVENT\_MOUSEWHEEL', 'EVENT\_RBUTTONDBLCLK', 'EVENT\_RBUTTONDOWN', 'EVENT\_RBUTTONUP'\] C++参考:http://blog.csdn.net/my\_lord\_/article/details/53927865 python:待续 [Grabcut]: http://www.cnblogs.com/mikewolf2002/p/3341418.html [setMouseCallback]: http://blog.csdn.net/qton_csdn/article/details/70193884
还没有评论,来说两句吧...