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您想要包含颜色的 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

与@moooeeeeep 建议的基本相同:

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 回答
1

要在 python 中将 roi 转换为灰度,您可以

  1. 将 roi 转换为灰色
  2. 通过合并灰色替换 roi,使得 [gray, gray, gray] 代替 BGR
  3. 现在投资回报率是灰色的。

    image = cv2.imread(image.jpg')
    h, w, _ = image.shape
    r, c, s = h//4, w//4, min(h,w)//2
    gray_portion = cv2.bitwise_not(cv2.cvtColor(image[r:r+s, c:c+s], cv2.COLOR_BGR2GRAY))
    merged = cv2.merge([gray_portion, gray_portion, gray_portion]) #IMPORTANT 
    image[r:r+s, c:c+s] = merged
    cv2.imshow(image)
    
于 2020-04-08T16:35:42.910 回答
0

对于那些想要反过来的人:-)

Mat tmp;
cvtColor(img, tmp, COLOR_BGR2GRAY);
cvtColor(tmp, tmp, COLOR_GRAY2BGR);
tmp(roi).copyTo(img(roi));
tmp = img;
于 2019-09-16T20:18:13.530 回答