OpenCV에서 alphamat을 사용해 보았습니다.

배경



현재 OpenCV에서 사소한 이미지 처리를 거쳐 간단한 설명하는 웹 페이지( h tps : // 훗 아츠레 포인 ts. jp/오펜 cv_도 c/ )를 작성 중입니다.

공식 OpenCV 문서 페이지 에서 찾습니다만, 이번은 contrib 모듈에 있는 alphamat 를 소개합니다.

alphamat는 머리카락이나 옷 등의 미세한 윤곽 영역까지 계산해 주는 모듈입니다.

Dataset



파쿠 타소 : 새로운 앱을 홍보하는 반짝이 홍보의 무료 자료
의 이미지를 사용하고 있습니다.



Create Map Image



이번 처리에서는 맵 이미지가 들어갑니다.
객체의 윤곽에 회색 영역을 지정하지만 툴로 pytorch + yolov3를 사용하여 마리오를 물체 감지하려고했습니다. 의 주석으로 사용한 labelme을 사용하고 있습니다.

json 형식의 어노테이션 파일을 사용할 수 있으므로 거기에서 영역을 읽고 fillPoly로 채 웁니다.
import cv2
import json
import numpy as np

def main():

    with open("woman.json") as fin:
        raw = json.load(fin)

        #背景色は黒
        dst = np.zeros((
            raw["imageHeight"], raw["imageWidth"], 3))
        dst += 0

        #人物は白で塗りつぶし
        for shapes in raw["shapes"]:
            if shapes["label"] == "person":
                person_contours = np.array(shapes["points"], dtype='int32') 
        cv2.fillPoly(dst, [person_contours], color=(255, 255, 255))

        #微細な輪郭エリアば灰色で塗りつぶし
        for shapes in raw["shapes"]:
            if shapes["label"] != "person":
                gray_contours = np.array(shapes["points"], dtype='int32')
                cv2.fillPoly(dst, [gray_contours], color=(127, 127, 127))

        cv2.imwrite('trimap.png', dst)

if __name__ == '__main__':
    main()




이것으로 맵 이미지는 완성.

프로세스



어쩌면 C++뿐입니다. 파이썬은 어쩌면 보인다. 만약 있다면 사센.
#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/core/utility.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/alphamat.hpp>

int main(int argc, const char* argv[])
{
    cv::String keys = "{src||}""{map||}";
    cv::CommandLineParser parser(argc, argv, keys);
    cv::String src_path = parser.get<cv::String>("src");
    cv::String map_path = parser.get<cv::String>("map");

    std::string name = "Effect";
    cv::Mat srcMat = cv::imread(src_path, cv::IMREAD_COLOR);
    cv::Mat mapMat = cv::imread(map_path, cv::IMREAD_GRAYSCALE);

    cv::Mat dst;

    cv::alphamat::infoFlow(srcMat, mapMat, dst);

    cv::namedWindow(name, cv::WINDOW_AUTOSIZE);

    while(true){

        cv::imshow(name, dst);
        int key = cv::waitKey(0);
        if (key == 27){
            break;
        } else if(key == 's'){
            cv::imwrite("output.png", dst);
        }
    }

    cv::destroyAllWindows();
    return 0;
}

make 
./main -src=[元画像のパス] -map=[マップ画像のパス]

Consequence



처리 결과는 이런 느낌이 되었습니다.



진짜로 회색 부분이 머리카락의 미세한 영역까지 계산해 줍니다.
그러나 계산 시간은 MacBookPro 메모리 16GB로 실행하면 2,3분이 걸렸습니다.

이 출력만으로도 오모로이다.

PostScript



여기에서 배경 이미지와 합성하고 싶습니다만, 어떻게 하면 좋을 것 같습니까?
역시, 윤곽 부분만을 채우고 흰 사촌만 트리밍하면 좋을까.
잘 모르겠어요.

Reference


  • Designing Effective Inter-Pixel Information Flow for Natural Image Matting
  • 좋은 웹페이지 즐겨찾기