How to convert IplImage to a matrix in OpenCV


Getting a digital image into numbers can be very handy for your image processing. In this post i will brief just that. I am a beginner in OpenCV and i found it very difficult to find material to do this. I was looking for storing a 8-bit image, 3 channel image into a 3D matrix. That's the method i am going to explain in this post.

Before i get on with the implementation, i would like to brief about the matrix structure that we are going to use. Its a 3D matrix; the row and column values represent the respective X and Y co-ordinates of the image. That is each value in the matrix represent a pixel. I am considering a 3 channeled image, so each pixel will have 3 channel values i.e for BGR. For more info on the matrix basic you can refer this link.

Following is the method I used..

First load a 8-Bit image with 3 channels RGB and create define a matrix structure accordingly.

          IplImage *img = cvLoadImage( "cataract.jpg");
    CvMat *mat = cvCreateMat(img->height,img->width,CV_32FC3 );

Next use the cvConvert function. cvConvert is a Macro provided by OpenCV which is the same as cvConvertScale() but is conventionally used when the scale and shift arguments will be let at their default values. 

           cvConvert( img, mat );

That does the work! Now your IplImage is stored into the matrix. You can retrieve the matrix values just by specifying the corresponding X,Y co-ordinate values in the cvGet2D function. I have used a for loop to print the RGB values of a small portion of the image.


        for(int i=0;i<10;i++)
        {
          for(int j=0;j<10;j++)
            {
               CvScalar scal = cvGet2D( mat,j,i);
               printf( "(%.f,%.f,%.f)  ",scal.val[0], scal.val[1], scal.val[2] );
            }
          printf("\n");
        }

cvScalar function is used to define a variable that stores the RBG value retrieved. You can check the OpenCV Reference links for some more tutorial links on OpenCV.

Please leave a comment so that know if this post is helpful or not. Also mention if any changes is required. It could help others :)



14 comments:

Suraj said...

hey thanks for the idea....
i need to do it for the sane for 1 bit channel image.... pls tel me how to do it

Adithya said...

Thanx Suraj..
You just need to make a small change for that..
First Load a a single channel image and while creating the matrix specify the type as CV_32FC1 indicating single channel..
Use the same cvGet2D to retrieve value.. Just you would just need to retrieve the first value..

Suraj said...

hey adithya,
how can i convert a matrix into an IplImage?

Adithya said...

For those looking for cvMat to IplImage conversion the below link should help..

http://bit.ly/kDF9P1

Ruginfo said...

Hey adithya; i want to identify a black spot in a white tablet.how could it be done??? btw this is very good post. Thanks for sharing it buddy...keep it up da gd work!!!!!!!!

Adithya said...

I am not clear with the white table but seems your problem could be solved using template matching..

RAGAV said...

how can i create new 400x300 pixel values into an image.what is the command for that

pruthviraj chavan said...

good afternoon,
i am pruthviraj chavan . i creating program which multiply color image with black & white image . is it possible???
if yes how??
plz help me....

kapil said...

what does it mean to 3 challen image........

Myblog said...

Thanks a lot Adity for your post

srlkhr3 said...

i got the outputs as all values as zero..how can i change it

Poormanphysics said...

Would the "cataract.jpg" be located where? In the project file? Would it be better to have a function parameter which points to the location? Would that be possible with cvLoadImage ()?

Jeison said...

hi,
for(int i=0;i<10;i++)
{
for(int j=0;j<10;j++)
{
CvScalar scal = cvGet2D( mat,j,i);
Debes cambiar la linea anterior asi

CvScalar scal = cvGet2D(mat,i,j)

Anonymous said...

hi i have a problem.

I have an image and I want to visualize the values ​​of your array.
to be able to modify.

my code is:
/**
* @function EqualizeHist_Demo.cpp
* @brief Test Mat
* @author OpenCV team
*/

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include
#include
#include "cv.h"

using namespace cv;
using namespace std;

/**
* @function main
*/
int main( int, char** argv )
{

/*imagem com canal 3 é criado por padrão. Se você precisa de uma imagem em tons de cinza, use: imread (filename, 0);*/
cv::Mat image= cv::imread("AngelinaJolie.ext"); // Read the file

if(! image.data ) // Check for invalid input
{
cout << "Could not open or find the image" << std::endl ;
cv::waitKey(5000);
return -1;
}

cv::namedWindow( "Display window", CV_WINDOW_AUTOSIZE );// Create a window for display.
imshow( "Display window", image );

//non so perchè ma senza il waitKey e lasciando solo il system pause non carica l'immagine...
cv::waitKey(5000);


// create new 450x350 image
cv::Mat img(Size(450,350),CV_8UC3);
// select a roi
cv::Mat roi(img, Rect(224,174,10,10));
//cor RGB inversa BGR (exemplo RGB = (0,0,255) - BGR = (255,0,0))
roi = Scalar(0,255,0);


return 0;

}

thank you

Post a Comment