【问题标题】:How to get negative of each channel (Red, Green, Blue) in RGB image?如何获得 RGB 图像中每个通道(红色、绿色、蓝色)的负值?
【发布时间】:2022-12-06 21:54:23
【问题描述】:

我正在尝试获取 RGB 图像中每个通道(红色、绿色、蓝色)的负值。
简单的说 :

  1. 如果 RGB 图像中红色通道的值为“r”,我希望得到 r'=255-r。
  2. 对绿色和蓝色也重复此过程。
  3. 最后合并r'、g'和b'来显示图像。

    下面是我写的代码,但它给出了:

    进程终止,状态为 -1073741819

    作为输出。另请参阅详细输出。

    #include<iostream>
    #include<opencv2/highgui/highgui.hpp>
    #include<opencv2/imgproc/imgproc.hpp>
    using namespace cv;
    using namespace std;
    //#include<filesystem>
    
    int main()
    {
       Mat myImage;//declaring a matrix to load the image//
       Mat different_Channels[3];//declaring a matrix with three channels//
       String imgPath = "C:/Users/tusha/Desktop/ResearchPractise/testNegativeImage/RGB.jpg";
       myImage= imread(imgPath,IMREAD_UNCHANGED);//loading the image in myImage matrix//
       split(myImage, different_Channels);//splitting images into 3 different channels//
       Mat b = different_Channels[0];//loading blue channels//
       Mat g = different_Channels[1];//loading green channels//
       Mat r = different_Channels[2];//loading red channels//
       //for red channel
       for (int y = 0; y < myImage.rows; y++) {
            for (int x = 0; x < myImage.cols; x++) {
                //Retrieving the values of a pixel
                int pixelr = r.at<uchar>(x,y);
                pixelr = 255-pixelr;
                r.at<uchar>(x,y)=pixelr;
                }
       }
    
       //for green channel
       for (int y = 0; y < myImage.rows; y++) {
            for (int x = 0; x < myImage.cols; x++) {
                //Retrieving the values of a pixel
                int pixelg = g.at<uchar>(x,y);
                pixelg = 255-pixelg;
                g.at<uchar>(x,y)=pixelg;
                }
       }
       //for blue channel
       for (int y = 0; y < myImage.rows; y++) {
            for (int x = 0; x < myImage.cols; x++) {
                //Retrieving the values of a pixel
                int pixelb = b.at<uchar>(x,y);
                pixelb = 255-pixelb;
                b.at<uchar>(x,y)=pixelb;
                }
       }
       vector<Mat> channels;
       channels.push_back(r);
       channels.push_back(g);
       channels.push_back(b);
       Mat negImage;
       merge(channels,negImage);
       cout<<"Negative image";
       namedWindow("Negative",WINDOW_NORMAL);
       imshow("Negative",negImage);
       return 0;
    }
    

【问题讨论】:

  • 你会很高兴听到你不需要任何人的帮助来解决这个问题,只需要一个你已经拥有的工具:你的调试器!这正是调试器的用途。它runs your program, one line at a time, and shows you what's happening,这是每个 C++ 开发人员都必须知道如何做的事情。在调试器的帮助下,您将能够快速找到此程序和您编写的所有未来程序中的所有问题,而无需向任何人寻求帮助。您是否尝试过使用调试器?如果不是,为什么不呢?你的调试器给你显示了什么?

标签: c++ opencv


【解决方案1】:

正如您在cv::Mat::at documentation 中看到的,您应该首先传递col(即您的y 坐标),然后是row(即您的x 坐标)。

因此,所有 6 行都指的是:

at<uchar>(x,y)

应改为:

at<uchar>(y,x)

您还可以删除传递给 cv::namedWindowWINDOW_NORMAL 参数,以便以实际大小查看结果图像,并在其后添加 cv::waitKey(0); 以保持窗口打开。

笔记使用cv::Mat::at 遍历所有像素相当效率低下.一种更有效的方法是每行使用 cv::Mat::ptr 来获取指向行数据的指针,然后使用指针算法遍历它。

旁注:最好避免 using namespace std - 请参阅此处 Why is "using namespace std;" considered bad practice?。类似的论点可以应用于using namespace cv;

【讨论】:

  • 我会修改关于 waitKey 的部分以说“必须”,因为 imshow 没有任何 waitKey (无论什么参数)是完全无用的(没有 GUI 事件得到处理,所以没有显示)。当然,在 OP 的代码中,它更没用,因为它是 return 之前的最后一条语句。
猜你喜欢
  • 2017-11-28
  • 1970-01-01
  • 2016-09-22
  • 1970-01-01
  • 1970-01-01
  • 2014-08-26
  • 2011-10-28
  • 1970-01-01
  • 2017-07-09
相关资源
最近更新 更多