LoginSignup
0
0

More than 3 years have passed since last update.

OpenCV・traincascade.exeのカスケード分類器学習用の正解画像のアノテーション作成プログラム(python3.7)

Posted at

はじめに

カスケード分類器のアノテーション作成プログラムが配布終わってた?ので自作

使用方法

正解オブジェクトをクリックしてマウスホイールで領域サイズ変更。比率は自分が使ったときの3:1になっているが適当に変えて使ってください。aで次の画像へ、dで指定したオブジェクト一つ削除、escで終了.
一枚に1つのオブジェクトがあることしか想定してない、増やす場合は一番下のfor文のところを適当に変えればたぶん動く

make_neg_img.py
#
# written by hdnkt 2020/10/26
#

import os
import cv2
import numpy as np


#マウスイベントの処理と四角形領域の保持
class Img_maker:
    sx = 0
    sy = 0
    gx = 0
    gy = 0
    boxes = []
    state = 0#0:押す前 1:押してる途中
    def __init__(self):
        self.sx = 0
        self.sy = 0
        self.gx = 0
        self.gy = 0
        self.boxes = []
        self.state = 0

    #マウスイベントの処理
    def mouse_event(self,event,x,y,flags,param):
        self.gx = x
        self.gy = y

        if event == cv2.EVENT_MOUSEWHEEL:
            if len(self.boxes)>0:
                if flags > 1:
                    self.boxes[len(self.boxes)-1][2]+=12
                    self.boxes[len(self.boxes)-1][3]+=4
                if flags < 0:
                    self.boxes[len(self.boxes)-1][2]-=12
                    self.boxes[len(self.boxes)-1][3]-=4

        if event == cv2.EVENT_LBUTTONDOWN:
            self.sx = x
            self.sy = y
            self.state = 1
        if event == cv2.EVENT_LBUTTONUP:
            self.gx = 120
            self.gy = 40
            self.boxes.append([self.sx,self.sy,self.gx,self.gy])
            self.state = 0

    #一番新しい長方形領域削除
    def pop_box(self):
        if len(self.boxes)<=0:
            return
        self.boxes.pop(len(self.boxes)-1)

    #指定された点の数
    def size_boxes(self):
        return len(self.boxes)

    #点から領域計算
    def calc(self):
        if len(self.boxes)==2:
            l=self.boxes[1][0]-self.boxes[0][0]
            return l*8//10
        else:
            return 1


    #領域全部教えます
    def get_boxes(self):
        for i in self.boxes:
            yield i

    #今何してる? 0:押し込んでいない 1:押し込み中 
    def get_state(self):
        return self.state

    #今描いてる四角の座標を返すよ 押し込み中しか呼ぶな
    def get_nowRect(self):
        if self.state == 0:
            return
        else:
            return self.sx,self.sy,self.gx,self.gy



if __name__ == "__main__":

    pre_path = "#正解画像をいれてあるフォルダのパス#"
    go_path = "#アノテーションファイルを書き出す場所のパス#/annotation.txt"
    subject_num = os.listdir(pre_path)

    #はじめからなら0でいいよ
    print("どこからはじめる")
    start = int(input())

    for i in range(start,len(subject_num)):
        i = subject_num[i]
        #画像を読み込み
        tmp_img = cv2.imread(pre_path+i)
        raw = tmp_img.copy()
        cv2.namedWindow(i)
        #画像メーカーをセットアップ
        img_Maker = Img_maker()
        cv2.setMouseCallback(i,img_Maker.mouse_event)
        #画面に画像を表示
        while 1:
            #お絵かきするためにコピーを用意
            tmp_img=raw.copy()
            if img_Maker.size_boxes()>0:
                for j in img_Maker.get_boxes():
                    cv2.rectangle(tmp_img, (j[0]-j[2]//2,j[1]-j[3]//2),(j[0]+j[2]//2,j[1]+j[3]//2), (255,255,255), thickness=2)
            cv2.imshow(i,tmp_img)

            end = False
            #キー操作
            k = 0
            k = cv2.waitKey(1)
            if k==ord("a"):#次の画像へ
                break
            if k==ord("d"):#一つ前の画像削除
                img_Maker.pop_box()
            if k==27:#結果を保存していったん終了
                end = True
                break

        #破壊する。それらは再生できない
        cv2.destroyAllWindows()
        print(i)

        for left in img_Maker.get_boxes():
            print(left)
            #1サンプル分のアノテーション作成

            with open(go_path,mode="a") as f:
                f.write("\n"+"path"+i+" 1 "+str(left[0]-left[2]//2)+" "+str(left[1]-left[3]//2)+" "+str(left[2])+" "+str(left[3]))

            if end:
                break
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0