OpenCV チートシート(Python)

OpenCVって顔検出できちゃうんですか。。。

ミーハーなので最近はAI戦士になりました。技術もですが汎用化も最近どんどん進んでるので、君らはAPIで呼び出してくれるだけで良いよ~と煽られてる気もして、ずるい、混ぜろ〜!という流れです。

あるはあるけど見やすいのがサクッと無かったのでネタになるかなと、ただデータ拡張とかの操作は結構pytorch内の関数もあるので使わないかもですね。いずれrails generate scaffold --face-detectでいける世界が。。。

基本操作系

画像の読み込み

img = cv2.imread('./sample.png')

    画像の保存

    cv2.imwrite('./sample.png', img)
    リサイズ
    img_resized = cv2.resize(img, (480,480))
    回転
    img_rotated = cv2.rotate(img, cv2.ROTATE_90_CLOCKWISE) #COUNTERCLOCKWISEで半時計回り

    画像の表示

    cv2.imshow("img", img)
    cv2.waitKey(0) #キーボードが押されるまで待機
    cv2.destroyAllWindows() #全てのウィンドウを閉じる
    

     

    簡易処理系

    結構難しい名前の色々な処理がありますのね。。。

    グレースケール化

    img_grayed = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    読み込み時点でグレースケール化する場合
    img_grayed = cv2.imread('dog_image.jpg',0)

    上下左右に反転

    img_flipx = cv2.flip(img, 0) #上下反転
    img_flipy = cv2.flip(img, 1) #左右反転

    アファイン変換(並行移動)

    t_x = 20 
    t_y = 60
    mat = np.float32([[1, 0, t_x], [0, 1, t_y]])
    img_affined = cv2.warpAffine(img, mat, (w, h))

    アファイン変換(せん断)

    theta1 = np.deg2rad(10)
    mat = np.float32([[1, np.tan(theta1), 0], [np.tan(theta2), 1, 0]])
    img_affined = cv2.warpAffine(img, mat, (w, h))

    RGBの色空間に変換

    img_converted = cv2.cvtColor(img0, cv2.COLOR_BGR2RGB) #pillowはRGB
    

    HSV空間に変換(色相、彩度、明度)

    img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

    色分解と結合

    img_bgr = cv2.split(img) 
    img_rgb = cv2.merge((img_bgr[2], img_bgr[1], img_bgr[0]))  # rgb順に色結合

    二値化(白黒画像、閾値125以上を255に変換)

    ret, img_bw = cv2.threshold(img, 125, 255, cv2.THRESH_BINARY)

    平滑化(ぼかし処理)

    img_blur = cv2.blur(img, (3,3))
    
    エッジ検出(Sobelフィルター)
    img_sobelx = cv2.Sobel(img, cv2.CV_32F, 1, 0, ksize=3)
    img_sobely = cv2.Sobel(img, cv2.CV_32F, 0, 1, ksize=3)

    エッジ検出(canny法)

    img_canny = cv2.Canny(img,10,180)

    ガンマ補正

    gamma = 0.4
    img = cv2.imread("src/Berry.jpg")
    gamma_cvt = np.zeros((256,1), dtype=np.uint8)
    for i in range(256):
        gamma_cvt[i][0] = 255 * (float(i)/255) ** (1.0 / gamma)
    img_gamma = cv2.LUT(img, gamma_cvt)

     

    描画系

    3色ヒストグラム

    colorList = ["blue","green","red"] #カラーリスト
    
    for i,j in enumerate(colorList):
        hist = cv2.calcHist(images   = [img], 
                            channels = [i],      # 画像のチャンネルのインデックス
                            mask     = None,     #全画素のヒストグラムを計算する場合 “None” 
                            histSize = [256], 
                            ranges   = [0,256]  
                           )
        plt.plot(hist, color=j) # ヒストグラム可視化

    文字の書き込み

    cv2.putText(img,
                text='test',
                org=(100, 300),
                fontFace=cv2.FONT_HERSHEY_SIMPLEX,
                fontScale=1.0,
                color=(0, 255, 0),
                thickness=2,
                lineType=cv2.LINE_4)

    四角形の描画

    cv2.rectangle(img,
                  pt1=(50, 150),
                  pt2=(125, 250),
                  color=(0, 255, 0),
                  thickness=3,
                  lineType=cv2.LINE_4,
                  shift=0)
    

    ポインターの描画

    cv2.drawMarker(img,
                   position=(200, 200),
                   color=(0, 0, 255),
                   markerType=cv2.MARKER_CROSS,
                   markerSize=20,
                   thickness=2,
                   line_type=cv2.LINE_4
                   )

     

    検出系

    これがどんどんハイクオリティになると面白くないな〜、僕にもaiやらせてください。

    画像の差分検出

    img_diff = cv2.absdiff(img_1, img_2)

    円を検出

    circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT,dp=1,minDist=70,
                                param1=100,param2=55,minRadius=10,maxRadius=0)

    QRコード検出

    qr = cv2.QRCodeDetector()
    data, points, straight_qrcode = qr.detectAndDecode(img)

    顔検出(学習済モデル利用)

    # カスケードファイル読み込み
    cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
    #顔検出(グレースケール化後)
    faces = cascade.detectMultiScale(img_gray)
    #検出した座標に矩形を描く
    for x, y, w, h in faces:
        cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)

    瞳検出

    #カスケードファイル読み込み
    eye_cascade = cv2.CascadeClassifier('haarcascade_eye.xml')
    #顔検出のfacesを利用
    for x, y, w, h in faces:
        face_gray = gray[y:y+h, x:x+w]
        eyes = eye_cascade.detectMultiScale(face_gray)
        for (ex, ey, ew, eh) in eyes:
            cv2.rectangle(face_color, (ex, ey), (ex+ew, ey+eh), (0, 255, 0), 1)
    

     

    その他参考資料

    チートシート記事って綺麗に書けば100万pvでしょウッヒョーって思ったのですが、無限にあるし綺麗に書けないわ-と諦めました。。。

    他にも色々出てくると思います!学習頑張らなくても動くもの色々ありますね!無いものは順次追加しますのでご指摘をー!

    【opencv動画まとめ】

    https://qiita.com/tokisugino/items/b2f022459a7f1320be08

    【opencv図形描画まとめ】

    https://note.nkmk.me/python-opencv-draw-function/

    おすすめの記事