Python 脚本/GUI 为 CascadeClassifier 生成正/负图像?

数据挖掘 分类 图像分类
2022-03-09 19:54:13

第一次,我在使用 OpenCV 包的级联分类器(后者也是新手)。我意识到编写我自己的 GUI/脚本以从我拥有的图像集中生成所需的正图像和负图像可能比在 Photoshop 或 Paint 中打开每个文件要快,但我也怀疑这已经做过很多次了前。

特别是,我正在寻找一种 GUI,它允许用户在目录中的文件中进行翻页,然后使用鼠标单击在特定图像上绘制矩形,并记录矩形的坐标以供以后使用。有什么建议么?如果没有,我一定会在/如果我完成这个时发布一个链接。这似乎是一种足够通用的实用程序,我很惊讶我在 OpenCV 包本身中找不到它。

2个回答

所以我写了剧本。它给了我一个学习 Tkinter 的借口。它贴在下面。请注意,这是一次性的,而不是良好编程实践的模型!如果有人使用它并且有错误或建议,请告诉我。这是git链接,模型代码粘贴在下面:

import Tkinter
import Image, ImageTk
from Tkinter import Tk, BOTH
from ttk import Frame, Button, Style
import cv2
import os
import time
import itertools

IMAGE_DIRECTORY =            # Directory of existing files
POSITIVE_DIRECTORY =         # Where to store 'positive' cropped images
NEGATIVE_DIRECTORY =         # Where to store 'negative' cropped images (generated automatically based on 'positive' image cropping
IMAGE_RESIZE_FACTOR =        # How much to scale images for display purposes. Images are not scaled when saved.

# Everything stuffed into one class, not exactly model programming but it works for now
class Example(Frame):

    def __init__(self, parent, list_of_files, write_file):
        Frame.__init__(self, parent)           
        self.parent = parent
        self.list_of_files = list_of_files
        self.write_file = write_file
        self.image = None
        self.canvas = None
        self.corners = []
        self.index = -1
        self.loadImage()
        self.initUI()
        self.resetCanvas()


    def loadImage(self):
        self.index += 1
        img = cv2.imread(self.list_of_files[self.index])            
        print(self.list_of_files[self.index])
        while not img.shape[0]:
            self.index += 1
            img = cv2.imread(self.list_of_files[self.index])            
        self.cv_img = img
        img_small = cv2.resize(img, (0,0), fx = IMAGE_RESIZE_FACTOR, fy = IMAGE_RESIZE_FACTOR)
        b, g, r = cv2.split(img_small)
        img_small = cv2.merge((r,g,b))
        im = Image.fromarray(img_small)
        self.image = ImageTk.PhotoImage(image=im)       

    def resetCanvas(self):        
        self.canvas.create_image(0, 0, image=self.image, anchor="nw")
        self.canvas.configure(height = self.image.height(), width = self.image.width())
        self.canvas.place(x = 0, y = 0, height = self.image.height(), width = self.image.width())

    def initUI(self):
        self.style = Style()
        self.style.theme_use("default")
        self.pack(fill=BOTH, expand=1)

        print "width and height of image should be ", self.image.width(), self.image.height()
        self.canvas = Tkinter.Canvas(self, width = self.image.width(), height = self.image.height())       
        self.canvas.bind("<Button-1>", self.OnMouseDown)
        self.canvas.pack()

        nextButton = Button(self, text="Next", command=self.nextButton)
        nextButton.place(x=0, y=0)

        restartButton = Button(self, text="Restart", command=self.restart)
        restartButton.place(x=0, y=22)       

    def nextButton(self):
        new_img = self.cv_img[self.corners[0][1]/IMAGE_RESIZE_FACTOR:self.corners[1][1]/IMAGE_RESIZE_FACTOR, self.corners[0][0]/IMAGE_RESIZE_FACTOR:self.corners[1][0]/IMAGE_RESIZE_FACTOR]
        files = self.list_of_files[self.index].split("/")
        try:
            os.stat(POSITIVE_DIRECTORY+files[-2])
        except:
            os.mkdir(POSITIVE_DIRECTORY+files[-2])
        print("saving to ", "{}{}/{}".format(POSITIVE_DIRECTORY, files[-2], files[-1]))
        cv2.imwrite("{}{}/{}".format(POSITIVE_DIRECTORY, files[-2], files[-1]), new_img)
        self.saveNegatives(files)
        self.restart()
        self.loadImage()
        self.resetCanvas()

    def saveNegatives(self, files):
        low_x = min(self.corners[0][0], self.corners[1][0])/IMAGE_RESIZE_FACTOR
        high_x = max(self.corners[0][0], self.corners[1][0])/IMAGE_RESIZE_FACTOR
        low_y = min(self.corners[0][1], self.corners[1][1])/IMAGE_RESIZE_FACTOR
        high_y = max(self.corners[0][1], self.corners[1][1])/IMAGE_RESIZE_FACTOR

        try:
            os.stat(NEGATIVE_DIRECTORY+files[-2])
        except:
            os.mkdir(NEGATIVE_DIRECTORY+files[-2])

        new_img = self.cv_img[ :low_y, :]
        cv2.imwrite("{}{}/{}{}".format(NEGATIVE_DIRECTORY, files[-2], "LY", files[-1]), new_img)
        new_img = self.cv_img[ high_y: , :]
        cv2.imwrite("{}{}/{}{}".format(NEGATIVE_DIRECTORY, files[-2], "HY", files[-1]), new_img)

        new_img = self.cv_img[ :, :low_x ]
        cv2.imwrite("{}{}/{}{}".format(NEGATIVE_DIRECTORY, files[-2], "LX", files[-1]), new_img)
        new_img = self.cv_img[:,  high_x: ]
        cv2.imwrite("{}{}/{}{}".format(NEGATIVE_DIRECTORY, files[-2], "HX", files[-1]), new_img)


    def restart(self):
        self.corners = []
        self.index -=1
        self.canvas.delete("all")
        self.loadImage()
        self.resetCanvas()


    def OnMouseDown(self, event):
        print(event.x, event.y)
        self.corners.append([event.x, event.y])
        if len(self.corners) == 2:
            self.canvas.create_rectangle(self.corners[0][0], self.corners[0][1], self.corners[1][0], self.corners[1][1], outline ='cyan', width = 2)


def main():

    root = Tk()
    root.geometry("250x150+300+300")

    list_of_files = []
    file_names = []
    walker = iter(os.walk(IMAGE_DIRECTORY))
    next(walker)
    for dir, _, _ in walker:
        files = [dir + "/" +  file for file in os.listdir(dir)]            
        list_of_files.extend(files)
        file_names.extend(os.listdir(dir))

    list_of_processed_files = []
    processed_file_names = []
    walker = iter(os.walk(POSITIVE_DIRECTORY))
    next(walker)
    for dir, _, _ in walker:
        files = [dir + "/" +  file for file in os.listdir(dir)]            
        list_of_processed_files.extend(files)
        processed_file_names.extend(os.listdir(dir))

    good_names = set(file_names) - set(processed_file_names)
    list_of_files = [f for i, f in enumerate(list_of_files) if file_names[i] in good_names] 

    app = Example(root, list_of_files, IMAGE_DIRECTORY+"positives")
    root.mainloop()  


if __name__ == '__main__':
    main()  

这是一篇类似的帖子,其中包含根据您的要求对有用的标签/注释工具的建议 - 浏览文件夹中的图像,在感兴趣的区域周围绘制一个矩形,将输出坐标保存到文件中。附加功能是标签,如“正面”、“负面”、“汽车”、“狗”等。

我最喜欢的工具是: