python for OpenCV图像处理之模板匹配以及分水岭算法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Eric_lmy/article/details/79085773

首先看些效果如下:
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

具体代码如下:

if __name__ == '__main__':
    from muban import Ui_Form
else:
    from muban.muban import Ui_Form
from PyQt5.QtWidgets import QWidget, QFileDialog
from PyQt5.QtCore import QFileInfo
import cv2
import numpy as np
from matplotlib.patches import Rectangle

class mubanWindows(QWidget):
    """docstring for mubanWindows"""
    # def __init__(self):
    #     super(mubanWindows, self).__init__()
    def init_fun(self):
        self.window = Ui_Form()
        self.window.setupUi(self)
        self.curFile = "匹配变换"

        self.window.mb_openmb_btn.clicked.connect(self.mb_openmb_btn_fun)
        self.window.mb_opensrc_btn.clicked.connect(self.mb_opensrc_btn_fun)
        self.window.mb_startpp_btn.clicked.connect(self.mb_startpp_btn_fun)
        self.window.mb_ddxpp_btn.clicked.connect(self.mb_ddxpp_btn_fun)

        self.window.H_lines_open_btn.clicked.connect(self.H_lines_open_btn_fun)
        self.window.H_yuan_open_btn.clicked.connect(self.H_yuan_open_btn_fun)
        self.window.H_lines_bh_btn.clicked.connect(self.H_lines_bh_btn_fun)
        self.window.H_yuan_bh_btn.clicked.connect(self.H_yuan_bh_btn_fun)

    def userFriendlyCurrentFile(self):
        return self.strippedName(self.curFile)

    def strippedName(self, fullFileName):
        return QFileInfo(fullFileName).fileName()

    def H_yuan_bh_btn_fun(self):
        img = self.h_yuan_img.copy()
        img = cv2.medianBlur(img, 5)
        cimg = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
        method = eval("cv2.HOUGH_" + self.window.H_yuan_method_comboBox.currentText())
        dp = self.window.H_yuan_dp_spinBox.value()
        circle = self.window.H_yuan_circles_spinBox.value()
        param1 = self.window.H_yuan_param1_spinBox.value()
        param2 = self.window.H_yuan_param2_spinBox.value()
        minRad = self.window.H_yuan_min_spinBox.value()
        maxRad = self.window.H_yuan_max_spinBox.value()
        circles = cv2.HoughCircles(img, method, dp, circle,
                            param1=param1, param2=param2, minRadius=minRad, maxRadius=maxRad)
        circles = np.uint16(np.around(circles))
        for i in circles[0, :]:
            cv2.circle(cimg, (i[0], i[1]), i[2], (0,255,0), 2)
            cv2.circle(cimg, (i[0], i[1]), 2, (0,0,255), 3)

        self.window.hough_figaxes.clear()
        self.window.hough_figaxes.imshow(cimg)
        self.window.hough_figaxes.autoscale_view()
        self.window.hough_figure.canvas.draw()

    def H_yuan_open_btn_fun(self):
        fileName = self.open_image_file()
        if fileName:
            #  self.hough_figure, self.hough_figaxes = plt.subplots()
            self.h_yuan_img = cv2.imread(fileName, 0)
            # b, g, r = cv2.split(self.h_yuan_img)
            imgret = self.h_yuan_img
            self.window.hough_figaxes.clear()
            self.window.hough_figaxes.imshow(imgret, cmap='gray')
            self.window.hough_figaxes.autoscale_view()
            self.window.hough_figure.canvas.draw()

    def H_lines_bh_btn_fun(self):
        img = self.h_lines_img.copy()
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        edges = cv2.Canny(gray, 50, 150, apertureSize=3)
        p = self.window.H_lines_p_spinBox.value()
        jingdu = self.window.H_lines_jd_doubleSpinBox.value()
        yuzhi = self.window.H_lines_yuzhi_spinBox.value()
        lines = cv2.HoughLines(edges, p, np.pi/int(jingdu), yuzhi)
        for rho,theta in lines[0]:
            a = np.cos(theta)
            b = np.sin(theta)
            x0 = a * rho
            y0 = b * rho
            x1 = int(x0 + 1000*(-b))
            y1 = int(y0 + 1000*(a))
            x2 = int(x0 - 1000*(-b))
            y2 = int(y0 - 1000*(a))
            cv2.line(img, (x1,y1), (x2,y2), (0,0,255), 2)

        b, g, r = cv2.split(img)
        imgret = cv2.merge([r,g,b])
        self.window.hough_figaxes.clear()
        self.window.hough_figaxes.imshow(imgret)
        self.window.hough_figaxes.autoscale_view()
        self.window.hough_figure.canvas.draw()

    def H_lines_open_btn_fun(self):
        fileName = self.open_image_file()
        if fileName:
            #  self.hough_figure, self.hough_figaxes = plt.subplots()
            self.h_lines_img = cv2.imread(fileName)
            b, g, r = cv2.split(self.h_lines_img)
            imgret = cv2.merge([r,g,b])
            self.window.hough_figaxes.clear()
            self.window.hough_figaxes.imshow(imgret)
            self.window.hough_figaxes.autoscale_view()
            self.window.hough_figure.canvas.draw()


    def mb_ddxpp_btn_fun(self):
        # method_str = "cv2." + self.window.mb_ff_comboBox.currentText()
        # method = eval(method_str)
        h = self.mu_img.shape[0]
        w = self.mu_img.shape[1]
        if hasattr(self, "mu_img") and hasattr(self, "src_img"):
            img = self.src_img.copy()
            res = cv2.matchTemplate(img, self.mu_img, cv2.TM_CCOEFF_NORMED)
            threshold = self.window.mb_yuzhi_doubleSpinBox.value() 

            loc = np.where(res >= threshold)
            for pt in zip(*loc[::-1]):
                cv2.rectangle(img, pt, (pt[0]+w, pt[1]+h), (0,0,255), 2)

            self.window.mb_figaxes2.clear()
            self.window.mb_figaxes2.imshow(res, cmap='gray')
            self.window.mb_figaxes2.autoscale_view()
            self.window.mb_figure2.canvas.draw()

            b, g, r = cv2.split(img)
            imgret = cv2.merge([r,g,b])
            self.window.mb_figaxes1.clear()
            self.window.mb_figaxes1.imshow(imgret)
            self.window.mb_figaxes1.autoscale_view()
            self.window.mb_figure1.canvas.draw()

    def mb_startpp_btn_fun(self):
        method_str = "cv2." + self.window.mb_ff_comboBox.currentText()
        method = eval(method_str)
        h = self.mu_img.shape[0]
        w = self.mu_img.shape[1]
        if hasattr(self, "mu_img") and hasattr(self, "src_img"):
            img = self.src_img.copy()
            res = cv2.matchTemplate(img, self.mu_img, method)
            min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
            if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]:
                top_left = min_loc
            else:
                top_left = max_loc

            bottom_right = (top_left[0]+w, top_left[1]+h)
            cv2.rectangle(img, top_left, bottom_right, (0,0,255) , 2)

            self.window.mb_figaxes2.clear()
            self.window.mb_figaxes2.imshow(res, cmap='gray')
            self.window.mb_figaxes2.autoscale_view()
            self.window.mb_figure2.canvas.draw()

            b, g, r = cv2.split(img)
            imgret = cv2.merge([r,g,b])
            self.window.mb_figaxes1.clear()
            self.window.mb_figaxes1.imshow(imgret)
            self.window.mb_figaxes1.autoscale_view()
            self.window.mb_figure1.canvas.draw()

    def mb_openmb_btn_fun(self):
        fileName = self.open_image_file()
        if fileName:
            self.mu_img = cv2.imread(fileName)
            b, g, r = cv2.split(self.mu_img)
            imgret = cv2.merge([r,g,b])
            self.window.mb_figaxes.clear()
            self.window.mb_figaxes.imshow(imgret)
            self.window.mb_figaxes.autoscale_view()
            self.window.mb_figure.canvas.draw()

    def mb_opensrc_btn_fun(self):
        fileName = self.open_image_file()
        if fileName:
            self.src_img = cv2.imread(fileName)
            b, g, r = cv2.split(self.src_img)
            imgret = cv2.merge([r,g,b])
            self.window.mb_figaxes1.clear()
            self.window.mb_figaxes1.imshow(imgret)
            self.window.mb_figaxes1.autoscale_view()
            self.window.mb_figure1.canvas.draw()

    def open_image_file(self):
        '''打开一个图像文件'''
        fileName, filetype= QFileDialog.getOpenFileName(self.window.widget, 
            "open file", '.', "jpg Files (*.jpg);;png Files (*.png);;All Files (*)")
        return fileName

if __name__ == '__main__':

    import sys
    from PyQt5.QtWidgets import QApplication , QMainWindow

    app = QApplication(sys.argv)
    mainW = QMainWindow()
    mainW.resize(1064, 667)
    ui = mubanWindows(mainW)
    ui.init_fun()
    mainW.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    from windows_ui import Ui_Form
else:
    from windows.grabcut.windows_ui import Ui_Form
from PyQt5.QtWidgets import QWidget, QFileDialog
from PyQt5.QtCore import QFileInfo
import cv2
import numpy as np
from matplotlib.patches import Rectangle

class grabcutWindows(QWidget):
    """docstring for mubanWindow"""
    # def __init__(self):
    #     super(mubanWindow, self).__init__()
    def init_fun(self):
        self.window = Ui_Form()
        self.window.setupUi(self)
        self.curFile = "GrabCut"

        self.window.fens_load_src_btn.clicked.connect(self.fens_load_src_btn_fun)
        self.window.fens_OK_btn.clicked.connect(self.fens_OK_btn_fun)

        self.window.tiqu_open_Src_btn.clicked.connect(self.fens_load_src_btn_fun)

        self.window.fs_figure1.canvas.mpl_connect("button_press_event", self.fs_figure1_on_press)
        self.window.fs_figure1.canvas.mpl_connect("button_release_event", self.fs_figure1_on_release)

        self.window.tiqu_tiqu_btn.clicked.connect(self.tiqu_tiqu_btn_fun)
        self.window.tiqu_xiugai_btn.clicked.connect(self.tiqu_xiugai_btn_fun)

    def fs_figure1_on_press(self, event):
        self.x0 = int(event.xdata)
        self.y0 = int(event.ydata)
        self.window.tiqu_x0_spinBox.setValue(self.x0)
        self.window.tiqu_y0_spinBox.setValue(self.y0)
        while len(self.window.fs_figaxes1.patches)>0:
                del self.window.fs_figaxes1.patches[0]
        self.fs_figure1_rect = Rectangle((0,0), 0, 0, linestyle='solid', fill=False, edgecolor='red')
        self.window.fs_figaxes1.add_patch(self.fs_figure1_rect)

    def fs_figure1_on_release(self, event):
        self.x1 = int(event.xdata)
        self.y1 = int(event.ydata)
        self.window.tiqu_x1_spinBox.setValue(self.x1)
        self.window.tiqu_y1_spinBox.setValue(self.y1)
        self.fs_figure1_rect.set_width(self.x1 - self.x0 + 1)
        self.fs_figure1_rect.set_height(self.y1 - self.y0 + 1)
        self.fs_figure1_rect.set_xy((self.x0, self.y0))
        self.window.fs_figure1.canvas.draw()

    def userFriendlyCurrentFile(self):
        return self.strippedName(self.curFile)

    def strippedName(self, fullFileName):
        return QFileInfo(fullFileName).fileName()

    def tiqu_xiugai_btn_fun(self):
        tiqu_img = self.img.copy()
        mask = np.zeros(self.tiqu_img.shape[:2], np.uint8)
        bgdModel = np.zeros((1,65), np.float64)
        fgdModel = np.zeros((1,65), np.float64)
        x0 = self.window.tiqu_x0_spinBox.value()
        y0 = self.window.tiqu_y0_spinBox.value()
        w = self.window.tiqu_x1_spinBox.value() - x0 + 1
        h = self.window.tiqu_y1_spinBox.value() - y0 + 1
        rect = self.frist_rect#(x0, y0, w, h)
        # 函数的返回值是更新的mask,bgdModel,fgdModel
        diecount = self.window.tiqu_diedai_spinBox.value()
        cv2.grabCut(tiqu_img, mask, rect, bgdModel, fgdModel, diecount, cv2.GC_INIT_WITH_RECT)
        # newmask = cv2.imread('./image/newmessi5.jpg', 0)
        # mask[newmask == 0] = 0
        # mask[newmask == 255] = 1
        if self.window.radioButton.isChecked():# 这里的这个方法需要改正,背景和前景一起标记出来才可以
            print("前景")
            mask[x0:w,y0:h] = 0
        else:
            mask[x0:w,y0:h] = 1
        mask, bgdModel, fgdModel = cv2.grabCut(tiqu_img,mask,None,bgdModel,fgdModel,5,cv2.GC_INIT_WITH_MASK)

        mask = np.where((mask==2)|(mask==0), 0, 1).astype('uint8')
        tiqu_img = tiqu_img*mask[:,:,np.newaxis]
        b, g, r = cv2.split(tiqu_img)
        imgret = cv2.merge([r,g,b])
        self.window.fs_figaxes2.clear()
        self.window.fs_figaxes2.imshow(imgret)
        self.window.fs_figaxes2.autoscale_view()
        self.window.fs_figure2.canvas.draw()

    def tiqu_tiqu_btn_fun(self):
        self.tiqu_img = self.img.copy()
        self.mask = np.zeros(self.tiqu_img.shape[:2], np.uint8)
        self.bgdModel = np.zeros((1,65), np.float64)
        self.fgdModel = np.zeros((1,65), np.float64)
        x0 = self.window.tiqu_x0_spinBox.value()
        y0 = self.window.tiqu_y0_spinBox.value()
        w = self.window.tiqu_x1_spinBox.value() - x0 + 1
        h = self.window.tiqu_y1_spinBox.value() - y0 + 1
        self.frist_rect = (x0, y0, w, h)
        # 函数的返回值是更新的mask,bgdModel,fgdModel
        diecount = self.window.tiqu_diedai_spinBox.value()
        cv2.grabCut(self.tiqu_img, self.mask, self.frist_rect, self.bgdModel, self.fgdModel, diecount, cv2.GC_INIT_WITH_RECT)

        self.mask = np.where((self.mask==2)|(self.mask==0), 0, 1).astype('uint8')
        self.tiqu_img = self.tiqu_img*self.mask[:,:,np.newaxis]
        b, g, r = cv2.split(self.tiqu_img)
        imgret = cv2.merge([r,g,b])
        self.window.fs_figaxes2.clear()
        self.window.fs_figaxes2.imshow(imgret)
        self.window.fs_figaxes2.autoscale_view()
        self.window.fs_figure2.canvas.draw()

    def fens_OK_btn_fun(self):
        if hasattr(self, 'img'):
            img = self.img.copy()
            gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
            ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
            # noise removal 
            kernel = np.ones((3,3), np.uint8)
            opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=2)
            # sure background area
            sure_bg = cv2.dilate(opening, kernel, iterations=3)
            dist = eval("cv2." + self.window.fens_dist_comboBox.currentText())
            diedai = self.window.fens_san_spinBox.value()
            dist_transform = cv2.distanceTransform(opening,dist,diedai)
            yuzhi = self.window.fens_yuzhi_doubleSpinBox.value()
            ret, sure_fg = cv2.threshold(dist_transform, yuzhi*dist_transform.max(), 255,0)
            # Finding unknown region
            sure_fg = np.uint8(sure_fg)
            unknown = cv2.subtract(sure_bg, sure_fg)
            # marker labelling 
            ret, markers1 = cv2.connectedComponents(sure_fg)
            # add one to all labels so that sure background is not 0, but 1
            markers = markers1+1
            # Now, mark the region of unkown with zero
            markers[unknown==255] = 0

            markers3 = cv2.watershed(img, markers)
            img[markers3 == -1] = [255, 0, 0]

            b, g, r = cv2.split(img)
            imgret = cv2.merge([r,g,b])
            self.window.fs_figaxes2.clear()
            self.window.fs_figaxes2.imshow(imgret)
            self.window.fs_figaxes2.autoscale_view()
            self.window.fs_figure2.canvas.draw()

    def fens_load_src_btn_fun(self):
        fileName = self.open_image_file()
        if fileName:
            self.img = cv2.imread(fileName)
            b, g, r = cv2.split(self.img)
            imgret = cv2.merge([r,g,b])
            self.window.fs_figaxes1.clear()
            self.window.fs_figaxes1.imshow(imgret)
            self.window.fs_figaxes1.autoscale_view()
            self.window.fs_figure1.canvas.draw()

    def open_image_file(self):
        '''打开一个图像文件'''
        fileName, filetype= QFileDialog.getOpenFileName(self.window.page, 
            "open file", '.', "jpg Files (*.jpg);;png Files (*.png);;All Files (*)")
        return fileName


if __name__ == '__main__':

    import sys
    from PyQt5.QtWidgets import QApplication , QMainWindow

    app = QApplication(sys.argv)
    mainW = QMainWindow()
    mainW.resize(1191, 686)
    ui = grabcutWindows(mainW)
    ui.init_fun()
    mainW.show()
    sys.exit(app.exec_())

ui文件地址如下:http://download.csdn.net/download/eric_lmy/10210088

另外,本人在gitChat上做了一个有关OpenCV和PyQt5完美结合的课程,http://blog.csdn.net/eric_lmy/article/details/78925072
使用微信扫码关注,领取课程

整个openCV第三章的图像处理讲义总结在:http://download.csdn.net/download/eric_lmy/10210158

打包的源码在:http://download.csdn.net/download/eric_lmy/10210167

猜你喜欢

转载自blog.csdn.net/Eric_lmy/article/details/79085773