OpenCV study notes: create/allocate images, read and write images and save, access and modify image pixels

Environment: CentOS7

g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-16)

$ pkg-config --modversion opencv
2.4.13

The following programs are compiled in the same way:

$g++ main.cpp `pkg-config --cflags --libs opencv`

1. Create\allocate image memory

#include<stdlib.h>
#include<stdio.h>
#include<math.h>
#include<cv.h>
#include<highgui.h>
#include<iostream>
using namespace std;
int main(int argc,char**argv)
{
    /**
    IplImage* cvCreateImage(CvSize size, int depth, int channels);
     size: cvSize(width,height);
    depth: pixel depth: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16U,
                  IPL_DEPTH_16S, IPL_DEPTH_32S, IPL_DEPTH_32F,
                  IPL_DEPTH_64F
    channels: Number of pixel channels. Can be 1, 2, 3 or 4.
    The channels are staggered. The data arrangement format of a color image is as follows:
        b0 g0 r0 b1 g1 r1 ...
    **/
    /*******Allocates memory for a new image******/
    //Allocate a 1channel byte image
    IplImage * img1 = cvCreateImage(cvSize(200,200), IPL_DEPTH_8U, 1);
    //Assign a 3channel floating point image
    IplImage * img2 = cvCreateImage(cvSize(200,200), IPL_DEPTH_32F,3);
    //copy image
    IplImage * img3 = cvCloneImage(img1);
    // release the image
    cvReleaseImage(&img1);
    cvShowImage("win1",img3);
    cvWaitKey(0);
    return 0;
}

2. Image reading, writing and saving

#include<stdlib.h>
#include<stdio.h>
#include<math.h>
#include<cv.h>
#include<highgui.h>
#include<iostream>
using namespace std;
int main(int argc,char**argv)
{
    /******Image read/write******/
    //read from file as image
    IplImage *img4 = 0;
    //This method is forced to convert to a three-channel color image by default
    img4 = cvLoadImage("wongrgb.jpg");
    /*
    img=cvLoadImage(fileName,flag);
        flag>0: three-channel color image
        flag=0: single channel grayscale image
        flag<0: The read channel is the same as the picture
    */
    //Force conversion to single channel graph
    img4 = cvLoadImage("wongrgb.jpg",0);
    if(!img4)
        printf("ERROR load Image.\n");

    /******Save image******/
    //cvSaveImage(outFileName,img); The format of the save is determined by the extension
    if(!cvSaveImage("wongrgb2.jpg",img4))
        printf("Could not save image.\n");

    //cvWaitKey(0);
    return 0;
}

3. Image pixel access and modification

#include<stdlib.h>
#include<stdio.h>
#include<math.h>
#include<cv.h>
#include<highgui.h>
#include<iostream>
using namespace std;

//First define a c++ wrapper 'Image', and then define different types of images based on Image:
template<class T> class Image
{
    private:
    IplImage* imgp;
    public:
    Image(IplImage* img=0) {imgp=img;}
    ~Image(){imgp=0;}
    void operator=(IplImage* img) {imgp=img;}
    inline T* operator[](const int rowIndx) {
        return ((T *)(imgp->imageData + rowIndx*imgp->widthStep));}
};
typedef struct{
    unsigned char b,g,r;
} RgbPixel;
typedef struct{
    float b,g,r;
} RgbPixelFloat;
typedef Image<RgbPixel> RgbImage;
typedef Image<RgbPixelFloat> RgbImageFloat;
typedef Image<unsigned char> BwImage;
typedef Image<float> BwImageFloat;

int main(int argc,char**argv)
{
    /*****Access image pixels******/
    /* indirect access */
    //For single-channel byte images
    IplImage *img5 = cvCreateImage(cvSize(200,200),IPL_DEPTH_8U,1);
    CvScalar s = cvGet2D(img5,50,50);//Access the pixel at row 50 and column 50
    printf("intensity = %f\n",s.val[0]);
    s.val[0] = 111;
    cvSet2D(img5,50,50,s);//Set the pixel value of (50,50) point
    cvShowImage("win1",img5);
    cvSaveImage("a.jpg",img5);
    //For multi-channel byte/float images
    IplImage *img6 = cvCreateImage(cvSize(200,200),IPL_DEPTH_32F,3);
    CvScalar s6 = cvGet2D(img6,50,50);
    printf("blue=%f, green=%f, red=%f\n",s6.val[0],s6.val[1],s6.val[2]);
    s6.val[0] = 111;
    s6.val[1] = 111;
    s6.val[2] = 111;
    cvSet2D(img6,50,50,s);
    cvShowImage("win2",img6);

    /*direct interview*/
    //For single-channel byte images (efficient, but error-prone)
    IplImage* img7=cvCreateImage(cvSize(200,200),IPL_DEPTH_8U,1);
    ((uchar *)(img7->imageData + 50*img7->widthStep))[40] = 255;//第50行40列
    cvShowImage("win3",img7);

    //For multi-channel byte images:
    IplImage* img8=cvCreateImage(cvSize(200,200),IPL_DEPTH_8U,3);
    ((uchar *)(img8->imageData + 50*img8->widthStep))[100*img8->nChannels + 0]=111;
    ((uchar *)(img8->imageData + 50*img8->widthStep))[100*img8->nChannels + 1]=112;
    ((uchar *)(img8->imageData + 50*img8->widthStep))[100*img8->nChannels + 2]=113;
    cvShowImage("win4",img8);

    //For multi-channel float images:
    IplImage* img9=cvCreateImage(cvSize(200,200),IPL_DEPTH_32F,3);
    ((float *)(img9->imageData + 100*img9->widthStep))[50*img9->nChannels + 0]=111;
    ((float *)(img9->imageData + 100*img9->widthStep))[50*img9->nChannels + 1]=112;
    ((float *)(img9->imageData + 100*img9->widthStep))[50*img9->nChannels + 2]=113;
    cvShowImage("win5",img9);

    int i, j, k;
    i = 50;
    j = 90;
    k = 1;
    /* Direct pointer-based access */
    //For single-channel byte images:
    IplImage* img10 = cvCreateImage(cvSize(200,200),IPL_DEPTH_8U,1);
    int height = img10->height;
    int width = img10->width;
    int step = img10->widthStep/sizeof(uchar);
    uchar * data = (uchar *) img10-> imageData;
    data[i*step+j] = 111;
    cvShowImage("win6",img10);

    //For multi-channel byte images:
    IplImage* img11 = cvCreateImage(cvSize(200,200),IPL_DEPTH_8U,1);
    int height11 = img11->height;
    int width11 = img11->width;
    int step11 = img11->widthStep/sizeof(uchar);
    uchar * data11 = (uchar *) img11-> imageData;
    data11[i*step11+j] = 111;
    cvShowImage("win7",img11);

    //For multi-channel floating-point images: (assuming the image data uses 4-byte (32bit) row alignment)
    IplImage* img12 = cvCreateImage(cvSize(200,200),IPL_DEPTH_32F,1);
    int height12 = img12->height;
    int width12 = img12->width;
    int step12 = img12->widthStep/sizeof(float);
    float* data12 = (float *)img12->imageData;
    data12[i*step12+j] = 111;
    cvShowImage("win8",img12);

    /*Direct access based on c++ wrapper: (simpler and more efficient): class: see the beginning of the program*/
    //For single-channel byte images:
    IplImage* img13=cvCreateImage(cvSize(200,200),IPL_DEPTH_8U,1);
    BwImage imgA(img13);
    imgA[i][j] = 111;
    cvShowImage("win9",img13);

    //For multi-channel byte images:
    IplImage* img14=cvCreateImage(cvSize(200,200),IPL_DEPTH_8U,3);
    RgbImage imgA14(img14);
    imgA14[i][j].b = 111;
    imgA14[i][j].g = 111;
    imgA14 [i] [j] .r = 111;
    cvShowImage("win10",img14);

    //For multi-channel float images:
    IplImage* img15=cvCreateImage(cvSize(200,200),IPL_DEPTH_32F,3);
    RgbImageFloat imgA15(img15);
    imgA15[i][j].b = 111;
    imgA15[i][j].g = 111;
    imgA15[i][j].r = 111;
    cvShowImage("win11",img15);

    cvWaitKey(0);
    return 0;
}
Code source: "OpenCV Chinese Reference Manual"

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325760442&siteId=291194637