gpt4 book ai didi

visual-c++ - OpenCV 手动将 RGB 转换为 YCbCr,反之亦然 (Visual C++)

转载 作者:太空宇宙 更新时间:2023-11-03 21:28:28 24 4
gpt4 key购买 nike

我想手动将我的 rgb 图像转换为 ycbcr 图像,反之亦然。但是有一个错误,我找不到。

我的图像看起来不像它们应该的样子。这是我的代码:

void YCbCrToRGB(IplImage* ScrY, IplImage* ScrCb, IplImage* ScrCr, IplImage* DesR, IplImage* DesG, IplImage* DesB){

for(int i=0; i < ScrY->height; i++){
for(int j=0; j < ScrY->width; j++){
double Y = (double)(ScrY->imageData + ScrY->widthStep*i)[j];
double Cb = (double)(ScrCb->imageData + ScrCb->widthStep*i)[j];
double Cr = (double)(ScrCr->imageData + ScrCr->widthStep*i)[j];

Cb = Cb -128;
Cr = Cr -128;
int r;
int g;
int b;

(DesR->imageData + DesR->widthStep*i)[j] = (int)(1 * Y + 0 * Cb + 1.4 * Cr);
(DesG->imageData + DesG->widthStep*i)[j] = (int)(1 * Y - 0.343 * Cb - 0.711 *Cr);
(DesB->imageData + DesB->widthStep*i)[j] = (int)(1* Y + 1.765 * Cb + 0* Cr);
}}

void RGBtoYCbCr(IplImage* ScrR, IplImage* ScrG, IplImage* ScrB, IplImage* DesY, IplImage* DesCb, IplImage* DesCr){
for(int i=0; i < ScrR->height; i++){
for(int j=0; j < ScrR->width; j++){
double R = (double)(ScrR->imageData + ScrR->widthStep*i)[j];
double G = (double)(ScrG->imageData + ScrG->widthStep*i)[j];
double B = (double)(ScrB->imageData + ScrB->widthStep*i)[j];

(DesY->imageData + DesY->widthStep*i)[j] = 0.299 *R + 0.587 *G + 0.114 *B;
(DesCb->imageData + DesCb->widthStep*i)[j] = -0.1687 *R - 0.3313 *G + 0.5 *B + 128;
(DesCr->imageData + DesCr->widthStep*i)[j] = 0.5 *R - 0.4187 *G - 0.0813 *B + 128;
}
}}

int _tmain(int argc, _TCHAR* argv[])
{
try {
IplImage* img = cvLoadImage( "C:\\sad-cat.jpg",1 );
cvNamedWindow( "Example1", CV_WINDOW_AUTOSIZE );
cvShowImage( "Example1", img );

IplImage *r = cvCreateImage(cvGetSize(img), img->depth, 1);
IplImage *g = cvCreateImage(cvGetSize(img), img->depth, 1);
IplImage *b = cvCreateImage(cvGetSize(img), img->depth, 1);

cvSplit(img, b, g, r, NULL);

IplImage *y = cvCreateImage(cvGetSize(img), img->depth, 1);
IplImage *cb = cvCreateImage(cvGetSize(img), img->depth, 1);
IplImage *cr = cvCreateImage(cvGetSize(img), img->depth, 1);


RGBtoYCbCr(r,g,b,y,cb,cr);

IplImage *ycbcr = cvCreateImage(cvGetSize(img), img->depth, 3);
cvMerge(y,cb,cr,NULL,ycbcr);

cvNamedWindow( "YCbCr from RGB", CV_WINDOW_AUTOSIZE );
cvShowImage( "YCbCr from RGB", ycbcr );



YCbCrToRGB(y,cb,cr,r,g,b);

IplImage *RGBfromYCbCr = cvCreateImage(cvGetSize(img), img->depth, 3);
cvMerge(r,g,b,NULL,RGBfromYCbCr);

cvNamedWindow( "RGB from YCbCr", CV_WINDOW_AUTOSIZE );
cvShowImage( "RGB from YCbCr", RGBfromYCbCr );

cvWaitKey(0);
return 0;
}
catch( exception& e){
std::cout<<("An error occurred.") << std::endl;
std::cout << e.what() <<std::endl; // Print the error message.
cvWaitKey(0);
}
}

这是带语法高亮的链接:http://paste2.org/p/1569904

我认为这是一个转换错误或类似的问题。非常感谢你

PS:公式和示例图片见评论(我不允许发布两个以上的链接或图片)

最佳答案

是的,这是一个类型转换问题。

        double Y = (double)(ScrY->imageData + ScrY->widthStep*i)[j];
double Cb = (double)(ScrCb->imageData + ScrCb->widthStep*i)[j];
double Cr = (double)(ScrCr->imageData + ScrCr->widthStep*i)[j];

应该是

        double Y = (uchar)(ScrY->imageData + ScrY->widthStep*i)[j];
double Cb = (uchar)(ScrCb->imageData + ScrCb->widthStep*i)[j];
double Cr = (uchar)(ScrCr->imageData + ScrCr->widthStep*i)[j];

RGBtoYCbCr的前三行做同样的改动。

此外,您还有舍入误差。您应该在分配之前对结果进行四舍五入:

        (DesY->imageData + DesY->widthStep*i)[j]   = round(     0.299    *R + 0.587  *G  + 0.114  *B);
(DesCb->imageData + DesCb->widthStep*i)[j] = round( -0.1687 *R - 0.3313 *G + 0.5 *B) + 128;
(DesCr->imageData + DesCr->widthStep*i)[j] = round( 0.5 *R - 0.4187 *G - 0.0813 *B) + 128;

最后,cvMerge(r,g,b,NULL,RGBfromYCbCr); 应该是 cvMerge(b,g,r,NULL,RGBfromYCbCr); 因为 cvShowImage 假定 BGR,而不是 RGB。

关于visual-c++ - OpenCV 手动将 RGB 转换为 YCbCr,反之亦然 (Visual C++),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6973115/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com