【问题标题】:OpenCV Mat image data structureOpenCV Mat 图像数据结构
【发布时间】:2017-03-04 09:57:26
【问题描述】:

我有一张经过处理的图像 throw:

//UIImage to Mat
cv::Mat originalMat = [self cvMatFromUIImage:inputImage];

//Grayscale
cv::Mat grayMat;
cv::cvtColor(originalMat, grayMat, CV_RGB2GRAY);

//Blur
cv::Mat gaussMat;
cv::GaussianBlur( grayMat , gaussMat, cv::Size(9, 9), 2, 2 );

//Threshold
cv::threshold(grayMat,tMat,100,255,cv::THRESH_BINARY);

比我想分析的(计算白点和黑点的数量)下面的线。例如:我有一个图像100x120px,我想检查x = 5y = from 0 to 119 所在的行;反之亦然x = 0..99; y = 5

所以我希望Mat 将包含x - Mat.colsy - Mat.rows,但看起来它以另一种方式保存数据。例如,我尝试将低于线条的像素颜色更改为线条但没有得到 2 条线条:

for( int x = 0; x < tMat.cols; x++ ){
    tMat.at<cv::Vec4b>(5,x)[0] = 100;
}

for( int y = 0; y < tMat.rows; y++ ){
    tMat.at<cv::Vec4b>(y,5)[0] = 100;
}
return  [self UIImageFromCVMat:tMat];

白色图像的结果:

为什么我没有得到 2 行?是否可以直接在Mat 中绘制\检查线?如果我要检查通过y = kx + b 计算的行怎么办?

【问题讨论】:

    标签: objective-c xcode opencv image-processing


    【解决方案1】:

    您以错误的方式访问像素值。您正在使用只有一个通道的图像,这就是为什么您应该像这样访问像素值:

    for (int x = 0; x < tMat.cols; x++){
        tMat.at<unsigned char>(5, x) = 100;
    }
    
    for (int y = 0; y < tMat.rows; y++){
        tMat.at<unsigned char>(y, 5) = 100;
    }
    

    Mat 元素的类型 由两个属性定义 - 通道数 和底层数据类型。如果您不知道这些术语的含义,我强烈建议您阅读有关方法 cv::Mat::type()cv::Mat::channels()cv::Mat::depth() 的文档。

    另外两个例子:

    mat.at<float>(x, y) = 1.0f; // if mat type is CV_32FC1
    mat.at<cv::Vec3b>(x, y) = Vec3b(1, 2, 3); // if mat type is CV_8UC3
    

    【讨论】:

      【解决方案2】:

      您的 Mat 数据类型可能存在问题。 threshold 的输出是 8 位或 32 位 (http://docs.opencv.org/2.4/modules/imgproc/doc/miscellaneous_transformations.html?highlight=threshold#threshold) 的单通道图像,因此您可能不应该使用 Mat.at&lt;Vec4b&gt;[0] 设置值。

      这是一个返回矩阵类型的函数。用法在注释掉的部分。复制自How to find out what type of a Mat object is with Mat::type() in OpenCV

      std::string type2str(int type){
      //string ty =  type2str( comparisonResult.type() );
      //printf("Matrix: %s %dx%d \n", ty.c_str(), comparisonResult.cols, comparisonResult.rows );
      
      string r;
      
      uchar depth = type & CV_MAT_DEPTH_MASK;
      uchar chans = 1 + (type >> CV_CN_SHIFT);
      
      switch ( depth ) {
      case CV_8U:  r = "8U"; break;
      case CV_8S:  r = "8S"; break;
      case CV_16U: r = "16U"; break;
      case CV_16S: r = "16S"; break;
      case CV_32S: r = "32S"; break;
      case CV_32F: r = "32F"; break;
      case CV_64F: r = "64F"; break;
      default:     r = "User"; break;
      }
      
      r += "C";
      r += (chans+'0');
      
      return r;}
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-03-09
        • 2021-10-01
        • 1970-01-01
        • 2015-04-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多