可视化的自动抠图器

可视化的自动抠图器

李兴球Python可视化自动抠图器演示选择

李兴球Python可视化自动抠图器演示选择
以下是所有完整源代码:

"""
   可视化的自动抠图器.py
   这是有可视化界面的自动抠图器,方便初级使用者
   使用方法,打开图像后,用鼠标指针选择要抠的区域,然后按抠图按钮。
   要保存为jpg图像!
"""
__author__ = '李兴球'
__date__ = '2020/5/6 21:36'
__blog__ = 'www.lixingqiu.com'

import os
import cv2
import numpy as np
from tkinter import *
from PIL import Image,ImageTk
from tkinter import filedialog

def cv_imread(file_path):
    """解决opencv的imread不能读取中文路径的问题"""
    cv_img = cv2.imdecode(np.fromfile(file_path,dtype=np.uint8),-1)
    return cv_img

def cv_imwrite(file_path):
    """解决opencv的imread不能读取中文路径的问题"""
    cv_img = cv2.imdecode(np.fromfile(file_path,dtype=np.uint8),-1)
    return cv_img

def mousedown_event(event):
    """按下处理"""
    global startx,starty
    startx = event.x - 2 
    starty = event.y - 2 

def mousemove_event(event):        
    global endx,endy,rect_item
    endx = event.x - 2 
    endy = event.y - 2
    rect = (startx,starty,endx,endy)
    canvas.coords(rect_item,*rect)
    window.title(rect)
    
def displa_pic():
    """在画布中显示这张图像"""
    global picfilename ,img,image_cv2
    #print(picfilename)
    image_cv2 = cv_imread(picfilename)
    #print(image_cv2)
    b,g,r = cv2.split(image_cv2)
    img = cv2.merge((r,g,b))
    im = Image.fromarray(img)
    img = ImageTk.PhotoImage(image=im) 
    
    w,h = img.width(),img.height()
    canvas.configure(width=w,height=h)
    canvas.itemconfig(canvas.img,image=img)

def dig_pic():
    """抠图"""
    global image_cv2

    rect = canvas.coords(rect_item)                 # 左上角坐标和宽高
    rect = (int(rect[0]),int(rect[1])
            ,int(rect[2]-rect[0]),int(rect[3]-rect[1]))
     
    mask = np.zeros(image_cv2.shape[:2], np.uint8)
    bgModel = np.zeros((1,65), np.float64)   
    fgModel = np.zeros((1,65), np.float64)

    cv2.grabCut(image_cv2, mask, rect, bgModel, fgModel, 5, cv2.GC_INIT_WITH_RECT)
    mask2 = np.where((mask == 2) | (mask == 0), 0, 1).astype(np.uint8)
     
    out = image_cv2 * mask2[:, :, np.newaxis]

    #cv2.imshow('风火轮编程自动抠图', out)
    #cv2.waitKey()
    # 把out写入到磁盘中,out是一个numpy的2d阵列.
    file_save = filedialog.asksaveasfilename()    
    #不能保存在中文路径cv2.imwrite(f,out,[int(cv2.IMWRITE_PNG_COMPRESSION),9]) 
    cv2.imencode('.jpg', out)[1].tofile(file_save)

def open_pic():
    """打开图像函数
       options为以下名称:
       -defaultextension, -filetypes, -initialdir,
       -initialfile, -multiple, -parent, -title, or -typevariable
    """
    global picfilename                        # 全局变量,要处理的图像文件名
    options = {'initialdir':os.getcwd(),
               'filetypes':[('png图像', '.png'),
                            ('jpg图像', '.jpg'),
                            ('jpeg图像', '.jpeg'),
                            ('gif图像', '.gif'),
                            ('bmp图像', '.bmp'),                            
                            ('all files', '*.*')]}
    picfilename = filedialog.askopenfilename(**options)
    if picfilename !=None or picfilename!="": displa_pic()

startx,starty,endx,endy = 0,0,0,0
rect_item = 0
picfilename = ''
image_cv2 = None

window = Tk()
window.title('可视化的自动抠图器_作者:李兴球 www.lixingqiu.com')
canvas = Canvas(window,width=1,height=1,bg="#e3e3e3")
canvas.pack(side=LEFT)

open_btn = Button(window,text='打开图像',command=open_pic)
open_btn.pack(side=RIGHT)

dig_btn = Button(window,text='抠图',command=dig_pic)
dig_btn.pack(side=RIGHT)

img = PhotoImage(width=1, height=1)
img.blank()
canvas.img = canvas.create_image(0,0,anchor=NW,image=img)
rect_item = canvas.create_rectangle(startx,starty,endx,endy,width=4,outline='red')

canvas.bind("",mousedown_event)
canvas.bind("",mousemove_event)

window.mainloop()

李兴球

李兴球的博客是Python创意编程原创博客

评论已关闭。