【问题标题】:how to convert image in to matrix using opencv?如何使用opencv将图像转换为矩阵?
【发布时间】:2011-11-13 16:14:44
【问题描述】:

我正在尝试在 OpenCV 中编写一个程序来将图像转换为矩阵形式,每个值代表图像的像素。我已将图像转换为二进制形式,现在我想将其像素值转换为矩阵。

【问题讨论】:

  • 您应该做的第一件事是添加一个代码示例,说明您目前已经获得了什么以及您想要什么。
  • 我已经添加了它并进一步解释。

标签: c++ visual-c++ opencv


【解决方案1】:

如果您需要使用 CvMat 对象,您可以尝试使用cvCopy 函数。它将 CvArr* 作为其参数,因此 IPLImage 和 CvMat 都适合。如果您想离开 C API 并使用更现代的东西,您可以使用 cv::Mat 对象将图像加载到并使用 C++ threshold

问题是你为什么要转换你已经拥有的矩阵格式(IPLImage 以及所有其他矩阵已经是矩阵)。如果您想要一个 bool 类型的矩阵,请使用 MatxMat_ 模板类。

【讨论】:

    【解决方案2】:

    乍一看您的问题会引发更多问题...尝试指定一点(我似乎无法看到您的代码示例,我是stackoverflow的新手) 例如,您打开的 cv 版本和 IDE(如代码块或 Microsoft Visual Studio)。但将其包含在您的问题中。我还想知道,这样做的目的是什么?为什么你需要一个矩阵等等:)

    尝试回答

    据我所知 “但我已经在 Visual C++ 2010 上安装了 OpenCV 2.3.1 版 – Ayesha Khan”

    OpenCV 使用名为 Mat 的类,你应该经常遇到。这个类本质上已经是一个矩阵了。如果我没记错的话,它与向量非常相似,我不会在这里介绍。

    因此,如果您需要访问其中的任何像素值,可以说。

    Mat Img;
    

    你会在这个类的实例中使用一个函数,就像这样

    cout << Img.at<uchar>(x,y);
    

    这将访问并打印坐标为 x,y 的像素值到控制台。在这个例子中,我在尖括号 中使用了 uchar。 uchar 用于 8 位图片。如果您使用更详细(更多位)的图像,则必须更改此设置。

    当使用二进制图片时,OpenCV 很可能会分配 8bit 的内存,也就是说你需要上面的例子。

    我想提供更多详细信息,但在您明确说明您正在尝试做什么之前。

    问候 Scrub @ Stackoverflow

    【讨论】:

      【解决方案3】:

      您的代码使用 OpenCV 版本 1。我会让其他人回答,因为这不是我的强项。在我看来,基于模板的 2.0 界面更加直观,我建议在所有新尝试中使用它。

      看看我在这个程序中使用 imread() 的方式... 请检查从 imread() 返回的值的类型... 另外,在代码中搜索originalColor = imageArg(/*row*/chosenX, /*column*/chosenY);这是一种索引到从imread返回的矩阵的方法

      // HW1 Intro to Digital Image Processing 
      // used OpenCV 2.3.1 and VS2010 SP1 to develop this solution
      
      #include "opencv2/core/core.hpp"
      #include "opencv2/highgui/highgui.hpp"
      #include <iostream>
      #include <cassert>
      
      using namespace cv;
      
      Mat_<Vec3b> image;
      int discreteAngles = 512;
      
      void on_mouse(int eventCode, int centerX, int centerY, int flags, void* params);
      int str2int(const std::string &str);
      
      int main(int argc, char* argv[])
      {
         // command itself is one element of argument array...
         if(argc != 1 && argc != 3)
         {
            std::cout << "Expecting two arguments to the application: angular granularity as a whole number and a file name." << std::endl;
            exit(0);
         }
      
         std::string discreteAnglesStr, fileName;
      
         if(argc == 3)
         {
            discreteAnglesStr = argv[1];
            fileName          = argv[2];
         }
         else
         {
            discreteAnglesStr = "64";
            fileName          = "boats.tif";
         }
      
         try
         {
            discreteAngles = str2int(discreteAnglesStr);
            auto image_ = imread(fileName);
            int channels = image_.channels();
            assert(channels == 3);
            image = image_;
      
            if(image.rows == 0)
               throw new std::exception();
      
            auto originalImageStr = "Original Image";
            namedWindow(originalImageStr);
            setMouseCallback(originalImageStr, on_mouse);
            imshow(originalImageStr, image);
         }
         catch(std::exception e)
         {
            std::cout << "could not load image." << std::endl;
         }
         waitKey(0);
         return -1;
      }
      
      // borrowed from http://stackoverflow.com/q/194465/90475, courtesy of Luka Marinko
      int str2int(const std::string &str)
      {
         std::stringstream ss(str);
         int num;
         if((ss >> num).fail())
         { 
            throw new std::exception("could not parse user input!");
         }
         return num;
      }
      
      double compute_max_madius(int imageRows, int imageCols, int centerX, int centerY)
      {
         auto otherX = imageCols - centerX;
         auto otherY = imageRows - centerY;
      
         auto a = sqrt((double)centerX * centerX + centerY * centerY);
         auto b = sqrt((double)otherX * otherX + centerY * centerY);
         auto c = sqrt((double)centerX * centerX + otherY * otherY);
         auto d = sqrt((double)otherX * otherX + otherY * otherY);
      
         return max(max(a,b), max(c,d));
      }
      
      Vec3b interpolate_with_nearest(const Mat_<Vec3b>& imageArg, double x, double y)
      {
         auto x0 = static_cast<int>(floor(x)); auto y0 = static_cast<int>(floor(y));
         auto x1 = static_cast<int>(ceil(x));  auto y1 = static_cast<int>(ceil(y));
      
         // Rolls over to the other side, esp. for angles
         if(x0 < 0) x0 = imageArg.rows - 1;
         if(y0 < 0) y0 = imageArg.cols - 1;
      
         if (x1 == imageArg.rows) x1 = 0;
         if (y1 == imageArg.cols) y1 = 0;
      
         int chosenX, chosenY;
         if (x - x0 < 0.5) chosenX = x0; else chosenX = x1;
         if (y - y0 < 0.5) chosenY = y0; else chosenY = y1;
      
         Vec3b originalColor = Vec3b(0, 0, 0);
         if (chosenX >= 0 && chosenX < imageArg.rows &&
            chosenY >= 0 && chosenY < imageArg.cols)
         {
            originalColor = imageArg(/*row*/chosenX, /*column*/chosenY);
         }
      
         return originalColor;
      }
      
      Vec3b interpolate_with_bilinear(const Mat_<Vec3b>& imageArg, double x, double y)
      {
         auto x0 = static_cast<int>(floor(x)); auto y0 = static_cast<int>(floor(y));
         auto x1 = static_cast<int>(ceil(x));  auto y1 = static_cast<int>(ceil(y));
      
         // Rolls over to the other side, esp. for angles
         if(x0 < 0) x0 = imageArg.rows - 1;
         if(y0 < 0) y0 = imageArg.cols - 1;
      
         if (x1 == imageArg.rows) x1 = 0;
         if (y1 == imageArg.cols) y1 = 0;
      
         if (!(
            x0 >= 0 && x0 < imageArg.rows &&
            x1 >= 0 && x1 < imageArg.rows &&
            y0 >= 0 && y0 < imageArg.cols &&
            y1 >= 0 && y1 < imageArg.cols))
            return Vec3b(0, 0, 0);
      
         auto f00 = imageArg(x0, y0);
         auto f01 = imageArg(x0, y1);
         auto f10 = imageArg(x1, y0);
         auto f11 = imageArg(x1, y1);
      
         auto b1 = f00;
         auto b2 = f10 - f00;
         auto b3 = f01 - f00;
         auto b4 = f00 + f11 - f01 - f10;
      
         x = x - x0;
         y = y - y0;
      
         return b1 + b2 * x + b3 * y + b4 * x * y;
      }
      
      void on_mouse(int eventCode, int centerX, int centerY, int flags, void* params)
      {
         if(eventCode == 0)
            return;
      
         switch( eventCode )
         {
         case CV_EVENT_LBUTTONDOWN:
            {
               std::cout << "Center was (" << centerX << ", " << centerY << ")" << std::endl;
      
               auto maxRadiusXY = compute_max_madius(image.rows, image.cols, centerX, centerY);
               int discreteRadii = static_cast<int>(floor(maxRadiusXY));
      
               Mat_<Vec3b> polarImg1;
               polarImg1.create(/*rows*/discreteRadii, /*cols*/discreteAngles);
      
               Mat_<Vec3b> polarImg2;
               polarImg2.create(/*rows*/discreteRadii, /*cols*/discreteAngles);
      
               for (int radius = 0; radius < discreteRadii; radius++) // radii
               {
                  for (int discreteAngle = 0; discreteAngle < discreteAngles; discreteAngle++) // discreteAngles
                  {
                     // 3
                     auto angleRad = discreteAngle * 2.0 * CV_PI / discreteAngles;
      
                     // 2
                     auto xTranslated = cos(angleRad) * radius;
                     auto yTranslated = sin(angleRad) * radius;
      
                     // 1
                     auto x = centerX + xTranslated;
                     auto y = centerY - yTranslated;
      
                     polarImg1(/*row*/ radius, /*column*/ discreteAngle) = interpolate_with_nearest(image, /*row*/y, /*column*/x);
                     polarImg2(/*row*/ radius, /*column*/ discreteAngle) = interpolate_with_bilinear(image, /*row*/y, /*column*/x);
                  }
               }
      
               auto polarImage1Str = "Polar (nearest)";
               namedWindow(polarImage1Str);
               imshow(polarImage1Str, polarImg1);
      
               auto polarImage2Str = "Polar (bilinear)";
               namedWindow(polarImage2Str);
               imshow(polarImage2Str, polarImg2);
      
               Mat_<Vec3b> reprocessedImg1;
               reprocessedImg1.create(Size(image.rows, image.cols));
      
               Mat_<Vec3b> reprocessedImg2;
               reprocessedImg2.create(Size(image.rows, image.cols));
      
               for(int y = 0; y < image.rows; y++)
               {
                  for(int x = 0; x < image.cols; x++)
                  {
                     // 1
                     auto xTranslated = x - centerX;
                     auto yTranslated = -(y - centerY);
      
                     // 2
                     auto radius = sqrt((double)xTranslated * xTranslated + yTranslated * yTranslated);
      
                     double angleRad;
                     if(xTranslated != 0)
                     {
                        angleRad = atan((double)abs(yTranslated) / abs(xTranslated));
      
                        // I Quadrant
                        if (xTranslated > 0 && yTranslated > 0)
                           angleRad = angleRad;
                        // II Quadrant
                        if (xTranslated < 0 && yTranslated > 0)
                           angleRad = CV_PI - angleRad;
                        // III Quadrant
                        if (xTranslated < 0 && yTranslated < 0)
                           angleRad = CV_PI + angleRad;
                        /// IV Quadrant
                        if (xTranslated > 0 && yTranslated < 0)
                           angleRad = 2 * CV_PI - angleRad;
      
                        if (yTranslated == 0)
                           if (xTranslated > 0) angleRad = 0;
                           else angleRad = CV_PI;
                     }
                     else
                     {
                        if (yTranslated > 0) angleRad = CV_PI / 2;
                        else angleRad = 3 * CV_PI / 2;
                     }
      
                     // 3
                     auto discreteAngle = angleRad * discreteAngles / (2.0 * CV_PI);
      
                     reprocessedImg1(/*row*/ y, /*column*/ x) = interpolate_with_nearest(polarImg1, /*row*/radius, /*column*/discreteAngle);
                     reprocessedImg2(/*row*/ y, /*column*/ x) = interpolate_with_bilinear(polarImg2, /*row*/radius, /*column*/discreteAngle);
                  }
               }
      
               auto reprocessedImg1Str = "Re-processed (nearest)";
               namedWindow(reprocessedImg1Str);
               imshow(reprocessedImg1Str, reprocessedImg1);
      
               auto reprocessedImg2Str = "Re-processed (bilinear)";
               namedWindow(reprocessedImg2Str);
               imshow(reprocessedImg2Str, reprocessedImg2);
      
            } break;
         }
      }
      

      【讨论】:

      • 谢谢,但我正在寻找将图像转换为矩阵的方法,我该怎么做?
      • 我已经编辑了我的摘要以便进一步解释。你能看看那个,让我知道吗?
      • 但我已经在 Visual C++ 2010 上安装了 OpenCV 2.3.1 版
      • 我想,像 CvMat *mat = cvCreateMat(img_bw->height,img_bw->width,CV_8UC3 );需要做的可能是
      • 我推荐阅读 www.amazon.com/OpenCV-Computer-Application-Programming-Cookbook/dp/1849513244
      猜你喜欢
      • 1970-01-01
      • 2017-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-29
      相关资源
      最近更新 更多