3

カラー画像を指定して、領域のみが色を持つ画像を取得したいと考えています。

Mat img = imread("lena.jpg");
Rect roi = Rect(100,  100, 300, 300);// only this should be in color in output

Mat img_yuv;
cvtColor(img, img_yuv, CV_RGB2YUV);
vector<Mat> channels(3);
split(img_yuv, channels);
Mat Y = channels[0];
Mat U = channels[1];
Mat V = channels[2];

// create mask
Mat mask = Mat::zeros(Y.size(), Y.type());
rectangle(mask, roi, Scalar(1), CV_FILLED);

// merging channels
channels[0] = Y;
channels[1] = U.mul(mask)+(Scalar::all(1)-mask).mul(Y);
channels[2] = V.mul(mask)+(Scalar::all(1)-mask).mul(Y);

Mat img_yuv_out, img_out;
merge(channels, img_yuv_out);
cvtColor(img_yuv_out, img_out, CV_YUV2RGB);
imshow("masked_color", img_out);
imshow("lena", img);

上記のopencvコードを使用すると、それぞれ入力画像と出力画像が表示されます。 入力 出力

Roi では問題なく動作しますが、画像の残りの部分はグレースケール画像のようには見えません (まだ 3 つのチャネルがあるため、正確ではありません。

4

4 に答える 4

5

これを試すことができます:

  1. 画像のコピーを取得し、それを 3 チャンネルのグレースケールに変換します (グレースケールを (色付きの) RGB に明示的に変換する必要があるかどうかはわかりません...)
  2. Matグレースケール コピー用に 1 回、元のカラー イメージ用に 1 回、色を入れたい ROI 用に を取得します。
  3. カラー イメージ ROI をグレースケール イメージ ROI に割り当てる/コピーする

実際、@AndreyKamaev が示唆するとおりです。

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

int main() {
    char const * const fname_in = "lena.jpg";
    char const * const fname_out = "lena_out.jpg";
    cv::Mat img = cv::imread(fname_in, CV_LOAD_IMAGE_COLOR);
    cv::Mat tmp;
    cv::cvtColor(img, tmp, CV_BGR2GRAY);
    cv::cvtColor(tmp, tmp, CV_GRAY2BGR);
    cv::Rect roi(100,  100, 300, 300);
    img(roi).copyTo(tmp(roi));
    img = tmp;
    cv::imwrite(fname_out, img);
}

出力画像:

変換されたレナ

于 2013-06-29T11:22:01.127 に答える
2

基本的に@moooeeeepが示唆するのと同じ:

Mat tmp;
cvtColor(img, tmp, COLOR_BGR2GRAY);
cvtColor(tmp, tmp, COLOR_GRAY2BGR);
img(roi).copyTo(tmp(roi));
img = tmp;
于 2013-06-29T11:53:52.620 に答える