【问题标题】:Opencv matrix values displayOpencv矩阵值显示
【发布时间】:2012-09-12 19:40:31
【问题描述】:

问题是:我使用 OpenCV v.2.4.2 加载灰度图像。 现在我想知道例如位置(0,0)处的像素值。 我试过了:

Mat image=imread("00001.jpg",1);
cvtColor(image,image,CV_RGB2GRAY);
int a=image.at<unsigned>(0,1);
printf("%d ",a);

这实际上是行不通的。如何获取任何数据类型(CV_8U、CV_32S ...)的像素值?

谢谢!!!

【问题讨论】:

  • 您使用的是 (0,1) 而不是 (0,0) ?

标签: opencv matrix


【解决方案1】:

首先,没有通用的方法可以通过这种方式获取像素值。这意味着如果您要使用at,则始终必须指定正确的值类型。在这种情况下,您应该使用a=image.at&lt;uchar&gt;(0,1);,因为您将图像转换为 8 位无符号灰度(1 通道)。

您也应该使用 CV_BGR2GRAY 而不是 RGB2GRAY,因为 OpenCV 使用 BGR 作为通道顺序。

您还可以从一开始就将图像读取为灰度,然后再次使用uchar

Mat image = imread("00001.jpg",0);    // note the 0 flag
int a=image.at<uchar>(0,1);
printf("%d ",a);

【讨论】:

    【解决方案2】:

    你在这里犯了两个错误。

    在读取图像时,您指定 1 作为输入参数。正如imread 所解释的,该函数可以读取三种不同格式的图像。

    CV_LOAD_IMAGE_UNCHANGED ( CV_LOAD_IMAGE_COLOR (>0) 加载RGB格式的图片

    对于您的情况,您必须使用 CV_LOAD_IMAGE_GRAYSCALE 作为第二个参数

    在您使用的下一步中:image.at&lt;unsigned&gt;(0,1); 不对应任何内容。你使用&lt;unsigned&gt;,但编译器说“未签名?未签名什么???”

    我认为更好的方法是使用正确的标签,例如 CV_LOAD_IMAGE_COLORCV_LOAD_IMAGE_GRAYSCALE。在下面的示例中,我将图像读入一个通道 (CV_LOAD_IMAGE_GRAYSCALE),它会自动将其转换为灰度。

    #include <cv.h>
    #include <highgui.h>
    
    #include <iostream>
    
    using namespace std;
    using namespace cv;
    
    int main()
    {
        Mat gImg = imread("img.png", CV_LOAD_IMAGE_GRAYSCALE);
    
        uchar val;
        val = gImg.at<uchar>(0,0);
    
        cout << (int)val << endl;
    
        imshow("showImg",gImg);
        cvWaitKey(0);
    
        return 1;
    }
    

    【讨论】:

    • 对,好吧,这行得通,但你试过这实际输出什么吗?就我而言,像素(0,0)得到-89。当图像是 8 位无符号时,这怎么可能?接下来我想问一下为什么要用uchar?
    • 当然我试过了。我不知道为什么您没有正确获得输出。我使用 UCHAR 的原因与@count0 在上面的评论中解释的原因完全相同,即它可以表示 0 到 255 之间的值
    • 您不能以这种方式使用 imread。第二个参数是 0、>0 或
    • 感谢鲍勃纠正我的错误。我现在将编辑答案。
    【解决方案3】:

    有一种简单的方法可以做到这一点。

    MatMat.data 给出一个指向原始数据矩阵的指针。

    要获取第n行第m列的像素值,

    Mat img = imread("filename.jpg",CV_LOAD_IMAGE_COLOR);
    unsigned char *input = (unsigned char*)(img.data);
    
    int i,j,r,g,b;
    for(int i = 0;i < img.cols;i++){
        for(int j = 0;j < img.rows;j++){
             b = input[img.cols * j + i ] ;
             g = input[img.cols * j + i + 1];
             r = input[img.cols * j + i + 2];
         }
     }
    

    所以,这是关于彩色图像的。对于灰度图像,

    Mat img = imread("filename.jpg",CV_LOAD_IMAGE_COLOR);
    Mat g;
    cvtColor(img, g, CV_BGR2GRAY);
    unsigned char *input = (unsigned char*)(g.data);
    
    int i,j,r,g,b;
    for(int i = 0;i < img.cols;i++){
        for(int j = 0;j < img.rows;j++){
             g = input[img.cols * j + i];
         }
     }
    

    阅读更多关于blogpost的信息。

    【讨论】:

      【解决方案4】:

      您可以尝试找出 opencv 用什么来表示它,以便更好地了解要使用的类型:

      cout << image.depth() << ", " << image.channels() << endl;
      

      还可以查看 discussion 关于元素访问的信息。

      【讨论】:

      • 好吧,我知道深度和通道,但是如果我知道矩阵是用于通常的图像 8 位和无符号整数,因此矩阵是 CV_8UC1,我应该将哪个参数传递给 Mat::at?正好到这里:image.at??????>(0,1);
      • CV_8UC1 表示 8 位无符号单通道,因此 unsigned char 表示从 0..255 开始的值。无符号整数将表示 0..65536 中的值,即 CV_16UC1。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-18
      • 2014-04-13
      • 2017-04-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多