OpenCV学习之基础知识

来源:互联网 发布:文虎考堂 数据库 编辑:程序博客网 时间:2024/05/21 06:38

OpenCV基础知识

命名规则

  1. 通用函数名cvActionTargetMod(…)

    • Action表示核心函数,如:Set、Creat等
    • target表示目标区域,如:轮廓、多边形
    • Mod表示可选变种,如:变量类型
  2. 通用矩阵数据类型CV_(bit_depth)(S|U|F)C(number_of_channels)

    • S表示带符号整数
    • U表示无符号整数
    • F表示浮点数
    • number_of_channels表示通道数
  3. 通用图像数据类型IPL_DEPTH_(bit_depth)(S|U|F),如IPL_DEPTH_8U表示8位无符号整数图像

  4. 头文件:cv.h、cvaux.h、highgui.h、cxcore.h

基本数据结构

  1. 图像结构IplImage
  2. 矩阵向量结构CvArr ,如:IplImage 、CvMat 、CvSeq
  3. 其他数据结构
(1)点的表示    CvPoint p = cvPoint(int x,int y);    CvPoint2D32f p = ...;    CvPoitn3D32f p = ...;    p.x=5.0;    p.y=5.0;(2)长方形维数的表示    表示长方形维数的数据结构及用法:    CvSize r = cvSize(int width, int height);    CvSizeD32f r = ...;(3)有偏移量的长方形表示    CvRect r = cvRect(int x,int y,int width,int height);

矩阵的使用与操作

  • 分配与释放矩阵
(1)分配矩阵    CvMat * M = cvCreateMat(int rows,int cols,int type);    其中,type为矩阵类型:CV_(bit_depth)(S|U|F)C(number_of_channels)(2)释放矩阵    cvReleaseMat(&M);(3)复制矩阵    M2 = cvCloneMat(M1);(4)初始化矩阵    CvMat Ma;    cvinitMatHeader(&Ma,3,4,CV_64FC1,a);(5)初始化单位矩阵    CvMat* M = cvCreateMat(4,4,CV_32FC1);    cvSetIdentity(M);
  • 访问矩阵元素
(1)直接访问    cvmSet(M,i,j,2.0);    t = cvmGet(M,i,j);(2)已知对齐方式直接访问    CvMat* M = cvCreateMat(4,4,CV_32FC1);    int n = M->cols;    float* data = M->data.fl;    data[i*n+j] = 3.0;(3)位置对齐方式直接访问    CvMat* M = cvCreateMat(...);    int step = M->step/sizeof(float);    float* data = M_>data.fl;    (data+i=step)[j] = 3.0;(4)直接访问一个已初始化的矩阵    doubel a[16];    CvMat Ma = cvMat(3,4,CV_64FC1,a);    a[i*4+j] = 2.0;

矩阵向量操作

(1)矩阵矩阵间的操作    cvAdd(M1,M2,M3);    //M1+M2->M3    cvSub(...); //M1-M2->M3    cvMatMul(...);  //M1*M2->M3(2)元素之间的操作    cvMul(...); //点乘,M1.*M2->M3    cvDiv(...); //点除    cvAddS(M1,cvScalar(-10.0),M3);  //点加减,M1.-10->M3(3)向量乘法操作    double v1[] = {1,2,3};    doubel...;    double v3[3];    CvMat V1 = cvMat(3,1,CVV_64FC1,v1);    CvMat...;    CvMar...;    doubel res = cvDotProduct(&V1,&V2); //V1点乘V2    cvCrossProduct(&V1,&V2,&V3); //叉乘->V3(4)单个矩阵的操作    CvMat *M1,*M2;    cvTranspose(M1,M2);//转置    CvScalar t = cvTrace(M1);//求对角线元素之和    double d = cvDet(M1);//求行列式值    cvInvert(M1,M2);//求矩阵的逆(5)非齐次线性系统求解    cvSolve(&A,&B,&x);(6)特征值分析操作(对称矩阵)    cvEigenVV(&A,&B,&C);//B为特征值,C为特征向量(7)奇异值分解    cvSVD(A,D,U,V,CV_SVD_U_T|CV_SVD_V_T);   //A=UDV*T标志使U和V以转置的方式返回(8)生成随机矩阵    rand()%1000;//1000以内的随机数

图像的操作

  • 读取图像
IplImage* img = 0;img = cvLoadImage("Lena.tif");if(!img) printf("打开错误!\n");
  • 保存图像
cvSavaImage("Lena.tif",img);
  • 访问图像元素
(1)间接方式    这是一种常用的方式,可以访问任何类型的图像,但是效率不高。    //对单通道单字节图像访问如下    IplImage* img = cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);    CvSalar s;    s = cvGet2D(img,i,j);    s.val[0]=111;    cvSet2D(img,i,j,s);    //对多通道浮点数(或者单字节)图像访问如下:    IplImage* img = cvCreateImage(cvSize(640,480),IPL_DEPTH_32U,3);    CvScalar s;    s = cvGet2D(img,i,j);//获取像素值    s.val[0]=111;    s.val[1]=111;    s.val[2]=111;    cvSet2D(img,i,j,s);(2)直接方式    //单通道    ((uchar*)(img->imageData + i*img->widthStep))[j] = 111;    //多通道,浮点数时用float替换uchar    ((uchar*)(img->imageData + i*img->widthStep))[j*img->nChannels+0] = 111;//B    ((uchar*)(img->imageData + i*img->widthStep))[j*img->nChannels+1] = 111;//G    ((uchar*)(img->imageData + i*img->widthStep))[j*img->nChannels+2] = 111;//R(3)用指针直接访问    在某种情况下,这种方式简单高效    //单通道    int height = img->height;    int width = img->width;    int step = img->widthStep/sizeof(uchar);    uchar* data = (uchar*)img->imageData;    data[i*step+j] = 111;    //多通道单字节    int height = img->height;    int width = img->width;    int step = img->widthStep/sizeof(uchar);    //浮点数相应变化uchar    int channels = img->nChannels;    uchar* data = (uchar*)img->imageData;   //浮点数相应变化uchar    data[i*step+j*channels+k] = 111;(4)用C++外壳直接访问    这是一种简单高效的方式    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;    //单通道    BwImage imgA(img);    imgA[i][j] = 111;    //多通道浮点数    RgbImageFloat imgA(img);    imgA[i][j].b = 111;    imgA[i][j].g = 111;    imgA[i][j].r = 111;
  • 图像转换
(1)将灰度图转为彩色图    cvConvertImage(srt,dst,flag=0);    其中src表示浮点(单字节)灰度(彩色)图    dst表示单字节灰度/彩色图。    flag为CV_CVTIMG_FLIP,垂直翻转;CV_CVTIMG_SWAP_RB,交换RB通道(2)彩色转灰度    cvCvtColor(cimg,gimg,CV_BGR2GRAY);    或者直接转换:    for(i=0;i<cimg->height;i++)        for(j=0;j<cimg->width;j++)        {            gimgA[i][j] = (uchar)(cimgA[i][j].b*0.114+                                    cimgA[i][j].g*0.587+                                    cimgA[i][j].r*0.299);        }        end    end(3)彩色空间转换    cvCvtColor(src,dst,code);    //code = CV_X2Y,XYRGBBGRGRAYHSVXYZLabLuvHLSYCrCb

绘制命令

(1)画矩形    //绘制一个以(100,100)、(200,200)为对角点,线粗为1的矩形,红色    cvRectangle(img,cvPoint(100,100),cvPoint(200,200),cvScalar(255,0,0),1);(2)画圆    //以(100,100)为圆心,20为半径的圆,绿色    cvCircle(img,cvPoint(100,100),20,cvScalar(0,255,0),1);(3)画线段    //在(100,100)-(200,200)间画粗为1的线段,绿色    cvLine(img,cvPoint(100,100),vPoint(200,200),cvScalar(0,255,0),1);(4)画多边形    CvPoint curve1[] = {10,10, 10,100, 100,100, 100,10};    CvPoint curve2[] = {30,30, 30,130, 130,130, 130,30, 150,10};    //一个正方形,一个多边形    CvPoint* curveArr[2] = {curve1,curve2};    int nCurvePts[2] = {4,5};    int nCurves = 2;    int isCurveClosed = 1;    int lineWidth = 1;    cvPolyLine(img,curveArr,nCurvePts,nCurves,isCurveClosed,cvScalar(255,0,255),lineWidth);(5)画填充的多边形    cvFillPoly(img, curveArr, nCurvePts, nCurves, cvScalar(255, 0, 255));(6)写字    #include "cv.h"      #include "highgui.h"      int main(int argc, char* argv[]){        IplImage *img = cvCreateImage(cvSize(256,256), 8, 3);        //写字        CvFont font;        double hScale = 1.0;        double vScale = 1.0;        int lineWidth = 3;        cvInitFont(&font, CV_FONT_HERSHEY_SIMPLEX | CV_FONT_ITALIC, hScale, vScale, 0, lineWidth);        cvPutText(img, "HelloWorld!", cvPoint(50, 50), &font, cvScalar(255, 255, 255));        cvNamedWindow("Example", CV_WINDOW_AUTOSIZE);        cvShowImage("Example",img);        cvWaitKey(0);        cvReleaseImage(&img);        cvDestroyWindow("Example");    }