読者です 読者をやめる 読者になる 読者になる

OpenCVを使ってある色以外は白黒にしてみる。

OpenCVを使ってある色以外は白黒にしてみる。

よくある処理に、ある色のみカラーにして他の色は白黒にして
ちょっと雰囲気のある写真にしたててみる。

オレンジ色のみ残して他の色を無くす(グレースケール)にしてみた。
ある色といってもRGBの数値でオレンジと示されても人間にはわからんので
直観的ででわかりやすいHSV色空間へいったん変更する。

https://ja.wikipedia.org/wiki/HSV%E8%89%B2%E7%A9%BA%E9%96%93
OpenCVでは色相(Hue)は0 - 180の範囲なので注意!!

HSV色空間へ変換した画像の色相(Hue)0〰20くらいまでのピクセル以外の
他の色のピクセルを全て彩度(Saturation)を0にすると色が無くなるのでグレースケールになる。
HSV色空間へ変換したあとRGB色空間へ戻すのをお忘れなく!!

//画面をだすよ
void display(cv::Mat image) {
    //名前をつける
    std::string windowName = "windowName";
    cv::namedWindow(windowName);
    //画面出た!!
    cv::imshow(windowName, image);
    //なにかキーをおして~
    cv::waitKey(1000 * 10);
    //整理整頓
    cv::destroyWindow(windowName);
}

//
// ここから
//
int main(int argc, char** argv) {

    cv::Mat image_ = cv::imread("fruits.jpg");
    cv::Mat ret_mat, hsv_image, dst_img;

    //HSV色空間へ
    cv::cvtColor(image_, hsv_image, CV_BGR2HSV);
    //HSV分解
    std::vector<cv::Mat> mat_channels;
    cv::split(hsv_image, mat_channels);

    //取り出す色を決定 0 - 20 まで
    int hue_min = 0;
    int hue_max = hue_min + 20;

    int hsv_value;
    int cols = hsv_image.cols;
    int rows = hsv_image.rows;
    for (int row = 0; row < rows; row++) {
        for (int col = 0; col < cols; col++) {
            hsv_value = static_cast<int>(mat_channels[0].at<uchar>(row, col));
            //色相(Hue)
            if (!((hue_min <= hsv_value) && (hsv_value <= hue_max))) {
                //彩度(Saturation)を0に
                mat_channels[1].at<uchar>(row, col) = 0;
            }
        }
    }
    //マージ
    cv::merge(mat_channels, dst_img);
    //RGB色空間へ (BGR)
    cv::cvtColor(dst_img, ret_mat, CV_HSV2BGR);

    //画面へ
    display(ret_mat);

    return 0;
}

オリジナル画像 f:id:treehitsuji:20170202175454j:plain

オレンジだけカラー画像 f:id:treehitsuji:20170202175458j:plain