将 YCrCb 图像拆分为其强度通道
Splitting YCrCb image to its intensity channels
我想将 YCrCb 拆分为 Y、Cr 和 Cb 通道。
代码运行良好,但是当我为每个 Y、Cr、Cb 显示带有 imshow("Y", y)
的通道时,所有通道看起来都是灰色的。
只有Y通道必须是灰色的,其他的应该是彩色的。我对吗?或者代码有什么问题?
Mat RGBImage;
RGBImage = imread("xx.jpg");
cvtColor(RGBImage, YCrCb, CV_RGB2YCrCb);
vector<Mat> ycc_planes;
split(YCrCb, ycc_planes);
Mat y = ycc_planes[0];
Mat Cr = ycc_planes[1];
Mat Cb = ycc_planes[2];
我的最终目标是对图像的 Y 分量应用均值滤波器,然后通过合并其他分量(Cr 和 Cb)将其改回 RGB。最后,我将获得原始 RGB 图像的模糊版本。但是我的平均过滤器 returns 总是灰色模糊图像。我虽然可能是因为我的 Cr,Cb 组件是灰色的。
正如@Miki said in the comments, splitting a 3-channel image will give you 3 1-channel images, and 1-channel images are grayscale! Also, @sturkmen 指出的一件重要的事情:OpenCV 图像存储为 BGR,因此您需要在 cvtColor
中使用 CV_BGR2YCrCb
而不是 CV_RGB2YCrCb
。
但是,我看到很多材料以丰富多彩的方式展示它们(各个频道),例如 Hays 教授的 this。
如果你想这样看,你需要为其他通道设置一个固定值,然后将它们合并回来。这样你就可以实现下图的第一行。第二行是各个频道。有关详细信息,您可以阅读此 post or watch this video.
当您将 3 通道图像拆分为 3 个单通道图像时,每个图像都是灰度图像。它们代表颜色信息的事实是无关紧要的。
原图:
YCrCb 频道:
但是,您可以应用颜色效果:
可以模糊Y通道,然后合并3个单通道,转回BGR:
完整代码供参考:
#include <opencv2/opencv.hpp>
#include <vector>
using namespace std;
using namespace cv;
int main()
{
Mat3b bgr = imread("path_to_image");
Mat3b ycrcb;
cvtColor(bgr, ycrcb, COLOR_BGR2YCrCb);
vector<Mat1b> planes;
split(ycrcb, planes);
// Collage planes
Mat1b collagePlanes(bgr.rows, bgr.cols*3);
for (int i = 0; i < 3; ++i)
{
planes[i].copyTo(collagePlanes(Rect(i*bgr.cols, 0, bgr.cols, bgr.rows)));
}
Mat1b gray(bgr.rows, bgr.cols, uchar(128));
// Y
vector<Mat1b> vy(3);
vy[0] = planes[0];
vy[1] = gray.clone();
vy[2] = gray.clone();
Mat3b my;
merge(vy, my);
// Cr
vector<Mat1b> vcr(3);
vcr[0] = gray.clone();
vcr[1] = planes[1];
vcr[2] = gray.clone();
Mat3b mcr;
merge(vcr, mcr);
// Cb
vector<Mat1b> vcb(3);
vcb[0] = gray.clone();
vcb[1] = gray.clone();
vcb[2] = planes[2];
Mat3b mcb;
merge(vcb, mcb);
// Collage planes
Mat3b collageColor(bgr.rows, bgr.cols * 3);
my.copyTo(collageColor(Rect(0, 0, bgr.cols, bgr.rows)));
mcr.copyTo(collageColor(Rect(bgr.cols, 0, bgr.cols, bgr.rows)));
mcb.copyTo(collageColor(Rect(2 * bgr.cols, 0, bgr.cols, bgr.rows)));
cvtColor(collageColor, collageColor, COLOR_YCrCb2BGR);
////////////////////////////
// Blur Y
boxFilter(planes[0], planes[0], CV_8U, Size(7,7));
Mat3b blurred;
merge(planes, blurred);
cvtColor(blurred, blurred, COLOR_YCrCb2BGR);
imshow("Original", bgr);
imshow("YCrCb planes", collagePlanes);
imshow("YCrCb planes colored", collageColor);
imshow("Blurred", blurred);
waitKey();
return 0;
}
我想将 YCrCb 拆分为 Y、Cr 和 Cb 通道。
代码运行良好,但是当我为每个 Y、Cr、Cb 显示带有 imshow("Y", y)
的通道时,所有通道看起来都是灰色的。
只有Y通道必须是灰色的,其他的应该是彩色的。我对吗?或者代码有什么问题?
Mat RGBImage;
RGBImage = imread("xx.jpg");
cvtColor(RGBImage, YCrCb, CV_RGB2YCrCb);
vector<Mat> ycc_planes;
split(YCrCb, ycc_planes);
Mat y = ycc_planes[0];
Mat Cr = ycc_planes[1];
Mat Cb = ycc_planes[2];
我的最终目标是对图像的 Y 分量应用均值滤波器,然后通过合并其他分量(Cr 和 Cb)将其改回 RGB。最后,我将获得原始 RGB 图像的模糊版本。但是我的平均过滤器 returns 总是灰色模糊图像。我虽然可能是因为我的 Cr,Cb 组件是灰色的。
正如@Miki said in the comments, splitting a 3-channel image will give you 3 1-channel images, and 1-channel images are grayscale! Also, @sturkmen 指出的一件重要的事情:OpenCV 图像存储为 BGR,因此您需要在 cvtColor
中使用 CV_BGR2YCrCb
而不是 CV_RGB2YCrCb
。
但是,我看到很多材料以丰富多彩的方式展示它们(各个频道),例如 Hays 教授的 this。
如果你想这样看,你需要为其他通道设置一个固定值,然后将它们合并回来。这样你就可以实现下图的第一行。第二行是各个频道。有关详细信息,您可以阅读此 post or watch this video.
当您将 3 通道图像拆分为 3 个单通道图像时,每个图像都是灰度图像。它们代表颜色信息的事实是无关紧要的。
原图:
YCrCb 频道:
但是,您可以应用颜色效果:
可以模糊Y通道,然后合并3个单通道,转回BGR:
完整代码供参考:
#include <opencv2/opencv.hpp>
#include <vector>
using namespace std;
using namespace cv;
int main()
{
Mat3b bgr = imread("path_to_image");
Mat3b ycrcb;
cvtColor(bgr, ycrcb, COLOR_BGR2YCrCb);
vector<Mat1b> planes;
split(ycrcb, planes);
// Collage planes
Mat1b collagePlanes(bgr.rows, bgr.cols*3);
for (int i = 0; i < 3; ++i)
{
planes[i].copyTo(collagePlanes(Rect(i*bgr.cols, 0, bgr.cols, bgr.rows)));
}
Mat1b gray(bgr.rows, bgr.cols, uchar(128));
// Y
vector<Mat1b> vy(3);
vy[0] = planes[0];
vy[1] = gray.clone();
vy[2] = gray.clone();
Mat3b my;
merge(vy, my);
// Cr
vector<Mat1b> vcr(3);
vcr[0] = gray.clone();
vcr[1] = planes[1];
vcr[2] = gray.clone();
Mat3b mcr;
merge(vcr, mcr);
// Cb
vector<Mat1b> vcb(3);
vcb[0] = gray.clone();
vcb[1] = gray.clone();
vcb[2] = planes[2];
Mat3b mcb;
merge(vcb, mcb);
// Collage planes
Mat3b collageColor(bgr.rows, bgr.cols * 3);
my.copyTo(collageColor(Rect(0, 0, bgr.cols, bgr.rows)));
mcr.copyTo(collageColor(Rect(bgr.cols, 0, bgr.cols, bgr.rows)));
mcb.copyTo(collageColor(Rect(2 * bgr.cols, 0, bgr.cols, bgr.rows)));
cvtColor(collageColor, collageColor, COLOR_YCrCb2BGR);
////////////////////////////
// Blur Y
boxFilter(planes[0], planes[0], CV_8U, Size(7,7));
Mat3b blurred;
merge(planes, blurred);
cvtColor(blurred, blurred, COLOR_YCrCb2BGR);
imshow("Original", bgr);
imshow("YCrCb planes", collagePlanes);
imshow("YCrCb planes colored", collageColor);
imshow("Blurred", blurred);
waitKey();
return 0;
}