凌的博客

您现在的位置是: 首页 > 学无止境 > python > 

python

简单的使用Pyqt5 识别图片边缘

2019-09-24 python 2027

图片识别部分:

import cv2
import numpy as np
import time

class ImageTool:
    def __init__(self):

        pass

    def img2gray(self, file, newfile):
        img = cv2.imread(file)
        qimg_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        cv2.imwrite(newfile, qimg_gray)

    def imgColor(self, img, color="r"):
        img = cv2.imread(img, cv2.IMREAD_COLOR)
        dt = dict()
        dt["r"] = img[:, :, 0]
        dt["g"] = img[:, :, 1]
        dt["b"] = img[:, :, 2]
        # r,g,b = cv2.split(img)
        return dt[color]

    def img2color(self, file, newfile, color="r"):
        img = cv2.imread(file)
        dt = dict()
        dt["r"] = img[:, :, 0]
        dt["g"] = img[:, :, 1]
        dt["b"] = img[:, :, 2]
        cv2.imwrite(newfile, dt[color])

    def imgGray(self, file):
        img = cv2.imread(file)
        return cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    def img2pos(self, img):
        h = img.shape[0]
        w = img.shape[1]
        color = np.array(img)

        filter = 100

        color_pos = dict()
        xs = []
        ys = []
        for x in range(w):
            for y in range(h):
                # print("x:%d ,y: %d" % (x,y))
                value = color[y][x]
                flag = 0
                if x - 1 >= 0 and x + 1 < w and y - 1 > 0 and y + 1 < h:
                    if color[y][x - 1] == 0 and value > filter:
                        flag = 1
                    elif color[y][x + 1] == 0 and value > filter:
                        flag = 1
                    elif color[y - 1][x] == 0 and value > filter:
                        flag = 1
                    elif color[y + 1][x] == 0 and value > filter:
                        flag = 1

                if flag == 1:
                    xs.append(x)
                    ys.append(y)
                    color_pos["{},{}".format(x, y)] = value
        return xs, ys, color_pos

    def imgEdge(self, img):
        xs, ys, pos = self.img2pos(img)
        maxX = max(xs)
        minX = min(xs)
        maxY = max(ys)
        minY = min(ys)
        return pos, minX, maxX, minY, maxY

    # img 缺口图片
    # mapimg 匹配的图片
    def match(self, img, mapimg):
        tool = ImageTool()
        mapimg = tool.imgGray(mapimg)
        img = tool.imgGray(img)
        edge, minX, maxX, minY, maxY = tool.imgEdge(img)
        # print(mapimg.shape)
        # print(img.shape)

        # 获取最大 概率 坐标
        rateX = 0
        maxRate = 0

        color = np.array(mapimg)

        for ix in range(0, mapimg.shape[1] - img.shape[1]):
            # print(ix,end="\t")
            rate = self.matchX(ix, mapimg.shape, color, edge, img.shape)
            print(rate, end="\t")

            if maxRate < rate:
                rateX = ix
                maxRate = rate

        print("\n匹配量: %d 最大可能位置:%d 权重:%.2f" % (len(edge), rateX + 3, maxRate))

    def matchX(self, ix, shape, color, edge):
        h = shape[0]
        w = shape[1]

        # 从左 向右 开始匹配  获取 左右两端 颜色色差总和最大的
        colorCount = 0

        for e_pos in edge:
            pos = e_pos.split(",")
            x = int(pos[0]) + ix
            y = int(pos[1])
            value = int(color[y][x])
            if x - 1 >= 0 and x + 1 < w:
                colorCount += abs(int(color[y][x - 1]) - value)

        return colorCount

        # img 缺口图片
        # mapimg 匹配的图片

    def matchFull(self, imgname, mapimgname, imgwh, mapimgwh, zoomx):
        img = cv2.imread(imgname, -1)
        img = cv2.resize(img, imgwh)
        # # exit()
        mapimg = cv2.imread(mapimgname)
        mapimg = cv2.resize(mapimg, mapimgwh, interpolation=cv2.INTER_AREA)
        #
        # img_ext = os.path.splitext(imgname)
        # img_resize = img_ext[0] + "_resize" + img_ext[1]
        # mapimg_ext = os.path.splitext(mapimgname)
        # mapimg_resize = mapimg_ext[0] + "_resize" + mapimg_ext[1]
        #
        # cv2.imwrite(img_resize, img)
        # cv2.imwrite(mapimg_resize, mapimg)
        #
        # mapimg = self.imgGray(mapimg_resize)
        # img = self.imgGray(img_resize)

        mapimg = cv2.cvtColor(mapimg, cv2.COLOR_BGR2GRAY)
        img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

        edge, minX, maxX, minY, maxY = self.imgEdge(img)
        # print(mapimg.shape)
        # print(img.shape)

        # 获取最大 概率 坐标
        rateX = 0
        maxRate = 0

        color = np.array(mapimg)

        for ix in range(0, mapimg.shape[1] - img.shape[1]):
            for iy in range(0, mapimg.shape[0] - img.shape[0]):
                # print(ix,end="\t")
                rate = self.matchXY(ix, iy, mapimg.shape, color, edge)
                # print(rate, end="\t")

                if maxRate < rate:
                    rateX = ix
                    maxRate = rate

        print("\n匹配量: %d 最大可能位置:%d 权重:%d" % (len(edge), rateX + zoomx, maxRate))
        return rateX + zoomx

    def matchXY(self, ix, iy, shape, color, edge):
        h = shape[0]
        w = shape[1]

        # 从左 向右 开始匹配  获取 左右两端 颜色色差总和最大的
        colorCount = 0

        for e_pos in edge:
            pos = e_pos.split(",")
            x = int(pos[0]) + ix
            y = int(pos[1]) + iy
            value = int(color[y][x])
            if x - 1 >= 0 and x + 1 < w and y - 1 >= 0 and y + 1 < h:
                colorCount += abs(int(color[y][x - 1]) - value)

        return colorCount

    def arr2txt(self, rgbx,min=0,max=255):
        a = np.array(rgbx)
        txt = []
        for y in a:
            tmptxt = ""
            for x in y:
                if x>=min and x <=max:
                    tmptxt += " "+str(int(x) + 1000)[1:4]
                else:
                    tmptxt += "    "

            txt.append(tmptxt)
        content = "\n".join(txt)
        return content
        # https://007.qq.com/online.html

    def img2color(self,img=None,file=""):

        if img is None:
            img = cv2.imread(file)
        else:
            img = np.asarray(img)

        dt = dict()
        dt["r"] = img[:, :, 0]
        dt["g"] = img[:, :, 1]
        dt["b"] = img[:, :, 2]
        dt["gray"] = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        return dt

    def img2txt(self, file="", txtfile="", img=None, color="gray"):
        dt = self.img2color(file=file,img=img)
        content = self.arr2txt(dt[color])
        if txtfile != "":
            with open(txtfile, "w+", encoding="utf-8") as f:
                f.write(content)
        return content


if __name__ == "__main__":
    start = time.time()
    tool = ImageTool()
    # 测试规则
    # tool.matchFull("./data/1.png", "./data/2.jpg",(56,56),(280,160),0)
    x = tool.matchFull("./data/1.png", "./data/2.jpg", (68, 68), (341, 195), 12)
    print(x + 2711 + 10)
    end = time.time()
    print("耗时:%.2f秒" % (end - start))


图形界面部分

1.png

import sys
from PyQt5.QtWidgets import QWidget,QMainWindow,QApplication,QDesktopWidget,QHBoxLayout,QVBoxLayout,QPushButton,QLineEdit,QSpinBox,QLabel,QFileDialog
from PyQt5.QtCore import Qt,QObject
from PyQt5.QtGui import QPixmap


class CombWidget(QObject):
    def __init__(self):
        super().__init__()

    def combHBox(self, lst: list):
        h = QHBoxLayout()
        for x, y in lst:
            h.addWidget(x, y)
        wg = QWidget()
        wg.setLayout(h)
        return wg

    def combVBox(self, lst: list):
        h = QVBoxLayout()
        for x, y in lst:
            h.addWidget(x, y)
        wg = QWidget()
        wg.setLayout(h)
        return wg

def Singletonfunc(cls):
    _instance = {}

    def _singleton(*args, **kargs):
        if cls not in _instance:
            _instance[cls] = cls(*args, **kargs)
        return _instance[cls]

    return _singleton



class Comimg(QMainWindow):

    def __init__(self):

        super().__init__()
        self.initUI()

    def initUI(self):

        self.status = self.statusBar()

        v = QVBoxLayout()
        comb = CombWidget()

        #self.imga =
        self.imga_btn = QPushButton("打开图片")
        self.imga_btn.clicked.connect(self.openImga)
        self.imgb_btn = QPushButton("打开图片")
        self.imgb_btn.clicked.connect(self.openImgb)
        self.imga_lbl = QLabel("")
        self.imgb_lbl = QLabel("")

        # 灰度图片
        self.imga_gray_lbl = QLabel("")
        self.imgb_gray_lbl = QLabel("")

        self.area_txt = QSpinBox()
        self.area_txt.setMaximum(100)
        self.area_txt.setValue(5)

        v.addWidget(comb.combHBox([(self.imga_btn,2),(QLabel(""),6),(self.imgb_btn,2),(QLabel(""),6),]),2)

        v.addWidget(
            comb.combHBox([(self.imga_lbl, 2),  ( self.imgb_lbl, 2), ]), 10)
        v.addWidget(
            comb.combHBox([(self.imga_gray_lbl, 2), (self.imgb_gray_lbl, 2), ]), 10)

        v.addWidget(comb.combHBox([(QLabel("容错范围"), 1),(self.area_txt, 2), (QPushButton("action"), 17), ]), 4)
        wg = QWidget()
        wg.setLayout(v)
        self.setCentralWidget(wg)
        print("init ui")
        self.setGeometry(300,300,800,600)
        self.setWindowTitle("识别图片")
        self.center()

    def openImga(self):
        self.status.showMessage("打开文件a")
        file, ok = QFileDialog.getSaveFileName(self,
                                               "选择图片",
                                               "C:/Users/Administrator/Desktop/",
                                               "图片文件 (*.png;*.jpg;*.gif)")
        if ok:
            self.imga_lbl.setPixmap(QPixmap(file.strip()))
            self.status.showMessage(file.strip())
            #self.imga_lbl.setScaledContents(True)

    def openImgb(self):
        self.status.showMessage("打开文件b")
        file, ok = QFileDialog.getSaveFileName(self,
                                               "选择图片",
                                               "C:/Users/Administrator/Desktop/",
                                               "图片文件 (*.png;*.jpg;*.gif)")
        if ok:
            self.imgb_lbl.setPixmap(QPixmap(file.strip()))
            self.status.showMessage(file.strip())
            #self.imgb_lbl.setScaledContents(True)


    def center(self):
        qr = self.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())


if __name__ == "__main__":
    app = QApplication(sys.argv)
    comimg = Comimg()
    comimg.show()
    sys.exit(app.exec_())


文章评论

0条评论