使用opencv和python写一段graphcuts的算法运行动画,要求写全,我不要框架
时间: 2024-09-25 16:12:00 浏览: 51
以下是使用Python和OpenCV实现Graph Cuts算法的一个完整示例代码,用于图像分割,并包含了基本的用户交互功能:
```python
from __future__ import print_function
import numpy as np
import cv2 as cv
import sys
# 定义各种颜色
BLUE = [255, 0, 0]
RED = [0, 0, 255]
GREEN = [0, 255, 0]
BLACK = [0, 0, 0]
WHITE = [255, 255, 255]
DRAW_BG = {'color': BLACK, 'val': 0}
DRAW_FG = {'color': WHITE, 'val': 1}
DRAW_PR_FG = {'color': GREEN, 'val': 3}
DRAW_PR_BG = {'color': RED, 'val': 2}
# 设置标志位
rect = (0, 0, 1, 1)
drawing = False
rectangle = False
rect_over = False
rect_or_mask = 100
value = DRAW_FG
thickness = 3
def onmouse(event, x, y, flags, param):
global img, img2, drawing, value, mask, rectangle, rect, rect_or_mask, ix, iy, rect_over
# 绘制矩形
if event == cv.EVENT_RBUTTONDOWN:
rectangle = True
ix, iy = x, y
elif event == cv.EVENT_MOUSEMOVE:
if rectangle == True:
img = img2.copy()
cv.rectangle(img, (ix, iy), (x, y), BLUE, 2)
rect = (min(ix, x), min(iy, y), abs(ix - x), abs(iy - y))
rect_or_mask = 0
elif event == cv.EVENT_RBUTTONUP:
rectangle = False
rect_over = True
cv.rectangle(img, (ix, iy), (x, y), BLUE, 2)
rect = (min(ix, x), min(iy, y), abs(ix - x), abs(iy - y))
rect_or_mask = 0
print("Now press the key 'n' a few times until no further change\n")
# 绘制触控曲线
if event == cv.EVENT_LBUTTONDOWN:
if rect_over == False:
print("First draw rectangle\n")
else:
drawing = True
cv.circle(img, (x, y), thickness, value['color'], -1)
cv.circle(mask, (x, y), thickness, value['val'], -1)
elif event == cv.EVENT_MOUSEMOVE:
if drawing == True:
cv.circle(img, (x, y), thickness, value['color'], -1)
cv.circle(mask, (x, y), thickness, value['val'], -1)
elif event == cv.EVENT_LBUTTONUP:
if drawing == True:
drawing = False
cv.circle(img, (x, y), thickness, value['color'], -1)
cv.circle(mask, (x, y), thickness, value['val'], -1)
if __name__ == '__main__':
print(__doc__)
# 加载图片
if len(sys.argv) == 2:
filename = sys.argv[1]
else:
print("No input image given, so loading default image, ../data/lena.jpg \n")
print("Correct Usage: python grabcut.py <filename> \n")
filename = 'H:/pictures/butterfly.jpg'
img = cv.imread(filename)
img2 = img.copy()
output = np.zeros(img.shape, np.uint8)
cv.namedWindow('output')
cv.namedWindow('input')
cv.setMouseCallback('input', onmouse)
cv.moveWindow('input', img.shape[1] + 10, 90)
print("Instructions:\n")
print("Draw a rectangle around the object using right mouse button\n")
while(1):
cv.imshow('output', output)
cv.imshow('input', img)
k = cv.waitKey(1)
if k == 27: # ESC to exit
break
elif k == ord('0'): # BG drawing
print("Mark background regions with left mouse button\n")
value = DRAW_BG
elif k == ord('1'): # FG drawing
print("Mark foreground regions with left mouse button\n")
value = DRAW_FG
elif k == ord('2'): # PR_BG drawing
value = DRAW_PR_BG
elif k == ord('3'): # PR_FG drawing
value = DRAW_PR_FG
elif k == ord('s'): # save image
bar = np.zeros((img.shape[0], 5, 3), np.uint8)
res = np.hstack((img2, bar, img, bar, output))
cv.imwrite('grabcut_output.png', res)
print("Results saved as image\n")
elif k == ord('r'): # reset everything
print("Resetting\n")
rect = (0, 0, 1, 1)
drawing = False
rectangle = False
rect_or_mask = 100
rect_over = False
value = DRAW_FG
img = img2.copy()
mask = np.zeros(img.shape[:2], dtype=np.uint8)
output = np.zeros(img.shape, np.uint8)
elif k == ord('n'): # segment the image
print("For finer touchups, mark foreground and background after pressing keys 0-3 and again press 'n'\n")
if (rect_or_mask == 0): # grabcut with rect
bgdmodel = np.zeros((1, 65), np.float64)
fgdmodel = np.zeros((1, 65), np.float64)
cv.grabCut(img2, mask, rect, bgdmodel, fgdmodel, 1, cv.GC_INIT_WITH_RECT)
rect_or_mask = 1
elif rect_or_mask == 1: # grabcut with mask
bgdmodel = np.zeros((1, 65), np.float64)
fgdmodel = np.zeros((1, 65), np.float64)
cv.grabCut(img2, mask, rect, bgdmodel, fgdmodel, 1, cv.GC_INIT_WITH_MASK)
mask2 = np.where((mask == 1) + (mask == 3), 255, 0).astype('uint8')
output = cv.bitwise_and(img2, img2, mask=mask2)
cv.destroyAllWindows()
```
这段代码实现了基本的GrabCut图像分割技术,允许用户绘制一个矩形框选择感兴趣的区域,并可以通过标记背景和前景来进行细化调整。注意,为了运行这个脚本,你需要安装OpenCV库,并且确保路径下的图像文件存在。
阅读全文