opencv基本数据结构

//<学习OPENCV>第3章
//数据结构基本操作

#include<cv.h>
#include<iostream>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include <cxcore.h>
#include<assert.h>

float sum( CvMat* mat );
void saturate_sv( IplImage* img );


int main(int argc,char** argv)
{
    //----------------------------------------------------------------------
    /**创建已知数据的OpenCV矩阵**/
    float vals[] = { 0.866025, -0.500000, 0.500000, 0.866025};
    //分配矩阵空间:行/列/类型
    //cvCreateMat = cvCreateMatHeader + cvCreateData + ...
    //cvCreateMatHeader:创建cvMat结构,不为数据分配内存
    //cvCreateData:只为数据的内存分配
    CvMat* mat = cvCreateMat(5, 5, CV_32FC1); //初始化为0,float,单通道
    
    //CV_MAT_ELEM宏存取矩阵元素,只对单通道矩阵有效
    float mat_3_2 = CV_MAT_ELEM( *mat, float, 3, 2 );
    printf("matrix created and accessed [3,2]=%f\n",mat_3_2);
    float mat_3_1 = 7.7;
    //CV_MAT_ELEM_PTR返回指向元素的指针
    *((float*)CV_MAT_ELEM_PTR(*mat,3,1)) = mat_3_1;
    
    //cvmSet,cvmGet用于处理浮点型单通道矩阵
    //通常情况下,set与get效率很低,一般定义自己的指针计算并且在矩阵中利用自己的方法
    cvmSet( mat, 2, 2, 0.5000 );
    cvSetReal2D( mat, 3, 3, 0.3300 );//2者等同
    printf("mat[3,1]=%f, [2,2]=%f, [3,3]=%f\n",CV_MAT_ELEM(*mat,float,3,1),CV_MAT_ELEM(*mat,float,2,2),CV_MAT_ELEM(*mat,float,3,3 ));
    cvWaitKey(0);

    //----------------------------------------------------------------------
    /**矩阵元素求和**/
    CvMat *mat1 = cvCreateMat(5,5,CV_32FC1);
    float mat1_3_2 = 7.7;
    *((float*)CV_MAT_ELEM_PTR(*mat1,3,2)) = mat1_3_2;
    cvmSet(mat1,4,4,0.5000);
    cvSetReal2D(mat1,3,3,0.5000);
    float s = sum(mat1);
    printf("the sum of mat1 is:%f\n",s);
    cvWaitKey();
    
    //----------------------------------------------------------------------
    /**访问图像数据**/
    //3通道图像,设置饱和度和高度,色度不变
    IplImage* img = cvLoadImage("D:\\My_Proj\\OPENCV\\dog.jpg");
    cvNamedWindow("origin",CV_WINDOW_AUTOSIZE);
    cvShowImage("origin",img);
    cvNamedWindow("saturate_sv",CV_WINDOW_AUTOSIZE);
    
    saturate_sv(img);
    cvShowImage("saturate_sv",img);
    cvSaveImage("D:\\My_Proj\\OPENCV\\saturate_sv.jpg",img);
    cvWaitKey(0);
    cvReleaseImage(&img);
    cvDestroyWindow("origin");
    cvDestroyWindow("saturate_sv");
    
    //----------------------------------------------------------------------
    /**设置图像ROI**/
    //ROI与WidthStep允许对图像的一小部分进行运算,提高执行速率
    IplImage* src;
    cvNamedWindow("image_pre", CV_WINDOW_AUTOSIZE);
    cvNamedWindow("image_post", CV_WINDOW_AUTOSIZE);  
    if((src=cvLoadImage("D:\\My_Proj\\OPENCV\\dog.jpg")) != 0)
    {
        //将字符串转换为整形,参数分别为ROI左上角坐标,长度和高度
        int x = 0;//atoi(argv[2]); 
        int y = 0;//atoi(argv[3]);
        int width = 300;//atoi(argv[4]);
        int height = 100;//atoi(argv[5]);
        int add = 255;//atoi(argv[6]); //
        cvShowImage("image_pre", src);
        cvSetImageROI(src, cvRect(x,y,width,height));//设置ROI,后面操作只对ROI区域
        
        //cvAdd:两个数组元素分别相加;cvAddS:数组元素分别与一个标量相加
        //cvScalar:4个double类型元素的数据,常用于初始化通道,存放三通道图像中像素:cvScalar(255,255,255)
        cvAddS(src,cvScalar(add),src);
        cvResetImageROI(src);//取消ROI
        cvShowImage( "image_post",src);
        cvWaitKey(0);
    }
    cvReleaseImage( &src );
    cvDestroyWindow("image_pre");
    cvDestroyWindow("image_post");   

    //----------------------------------------------------------------------
    /**利用WidthStep设置ROI**/ 
    //ROI set和reset只能串行处理ROI
    //当需要对图像中多个ROI同时处理时,则用WidthStep
    IplImage* interest_img;//初始图像
    CvRect interest_rect;//设置2个ROI区域
    CvRect interest_rect1;

    if(((interest_img=cvLoadImage("D:\\My_Proj\\OPENCV\\dog.jpg")) != 0 ))
    {
        interest_rect.x = 0;
        interest_rect.y = 0;
        interest_rect.width = 200;
        interest_rect.height = 200;
        int add = 100;
        
        interest_rect1.x = 200;
        interest_rect1.y = 200;
        interest_rect1.width = 100;
        interest_rect1.height = 100;
        int add1 = 200;

        //设置子图像区域
        //创建IplImage图像头,制定图像的尺寸,深度和通道数,不包括数据区域
        IplImage *sub_img = cvCreateImageHeader(
            cvSize(interest_rect.width, interest_rect.height),
            interest_img->depth,interest_img->nChannels);

        IplImage *sub_img1 = cvCreateImageHeader(
            cvSize(interest_rect1.width,interest_rect1.height),
            interest_img->depth,interest_img->nChannels);

        //设置图像显示属性,origin=0表示左上角为原点,=1为左下角
        sub_img->origin = interest_img->origin;
        //widthStep:存储一行像素所需字节数,补足4的倍数。
        sub_img->widthStep = interest_img->widthStep;
        sub_img->imageData = interest_img->imageData + //起始数据域
          interest_rect.y * interest_img->widthStep  +
          interest_rect.x * interest_img->nChannels;
        
        sub_img1->origin = interest_img->origin;
        //widthStep:存储一行像素所需字节数,补足4的倍数。
        sub_img1->widthStep = interest_img->widthStep;
        sub_img1->imageData = interest_img->imageData + //起始数据域
          interest_rect1.y * interest_img->widthStep  +
          interest_rect1.x * interest_img->nChannels;

        //对ROI区域进行操作,结果反映在原图像上
        cvAddS(sub_img,cvScalar(add),sub_img );
        cvAddS(sub_img1,cvScalar(add1),sub_img1 );

        cvNamedWindow( "WidthStep", CV_WINDOW_AUTOSIZE );
        cvShowImage( "WidthStep", interest_img );

        cvReleaseImageHeader(&sub_img);
        cvReleaseImageHeader(&sub_img1);
        cvDestroyWindow("WidthStep");  

        cvWaitKey();
    }
    
    //----------------------------------------------------------------------
    /**2个数据加权相加**/
    //cvAddWeighted:src1*alpha+src2*beta+gamma
    IplImage *src1, *src2;
    if(((src1=cvLoadImage("D:\\My_Proj\\OPENCV\\dog.jpg")) != 0)&&((src2=cvLoadImage("D:\\My_Proj\\OPENCV\\saturate_sv.jpg"))!=0))
    {
        int x = 200;
        int y = 200;
        int width = 100;
        int height = 100;
        double alpha = 0.3;
        double beta  = 0.5;//(double)atof(argv[8]);
        cvSetImageROI(src1, cvRect(x,y,width,height));
        cvSetImageROI(src2, cvRect(0,0,width,height));
        //cvAddWeighted:src1*alpha+src2*beta+0
        //2个源图像、一个目的图像
        cvAddWeighted(src1,alpha,src2,beta,0.0,src1);
        cvResetImageROI(src1);
        cvNamedWindow( "Alpha_blend", 1 );
        cvShowImage( "Alpha_blend", src1 );
        cvWaitKey();

        cvReleaseImage(&src1);
        cvReleaseImage(&src2);
        cvDestroyWindow("Alpha_blend");
    }
    else 
        printf("Couldn't load one or both of %s, %s\n",argv[1],argv[2]);
      
    //----------------------------------------------------------------------
    /**写入xml:以xml的格式保存数据**/
    CvMat *the_matrix_data = cvCreateMat(5,5,CV_32FC1);
    float the_matrix_data_3_2 = 7.7;
    *((float*)CV_MAT_ELEM_PTR( *the_matrix_data, 3,2) ) = the_matrix_data_3_2;
    cvmSet(the_matrix_data,4,4,0.5000);
    cvSetReal2D(the_matrix_data,3,3,0.5000);

    CvMat A = cvMat(5,5,CV_32F,the_matrix_data);

    printf("Saving my_matrix.xml\n");
    cvSave( "D:\\My_Proj\\OPENCV\\my_matrix.xml", &A );
    // to load it then in some other program use …
    printf("Loading my_matrix.xml\n");
    CvMat* A1 = (CvMat*)cvLoad("D:\\My_Proj\\OPENCV\\my_matrix.xml");
    
    cvWaitKey(0);
    
    //----------------------------------------------------------------------
    /**写配置文件**/
    CvMat *cmatrix = cvCreateMat(5,5,CV_32FC1);
    float cmatrix_3_2 = 7.7;
    *((float*)CV_MAT_ELEM_PTR( *cmatrix, 3,2) ) = cmatrix_3_2;
    cvmSet(cmatrix,4,4,0.5000);
    cvSetReal2D(cmatrix,3,3,0.5000);
    printf("writing cfg.xml\n");
    CvFileStorage* fs = cvOpenFileStorage("D:\\My_Proj\\OPENCV\\cfg.xml",0,CV_STORAGE_WRITE);
    cvWriteInt(fs, "frame_count", 10 );//写入整形数据
    cvStartWriteStruct(fs,"frame_size",CV_NODE_SEQ);//写入数据结构
    cvWriteInt(fs,0,320 );
    cvWriteInt(fs,0,200 );
    cvEndWriteStruct(fs);
    cvWrite( fs,"color_cvt_matrix",cmatrix);
    cvReleaseFileStorage(&fs);
}

//求CvMat数组元素和
//计算指向矩阵的指针,注意矩阵元素data是联合体。
//引用这个指针解时,需要指明结构体中的正确的元素一边得到正确的指针类型
float sum( CvMat* mat ) 
{
    float s = 0.0f;
    for( int row=0; row<mat->height; row++ ) 
    {
        //data union中fl指针(指向float数据),step是以1字节来计算的(每行数据位宽step字节),实际步长为mat->step/4(浮点数的长度为4字节)
        float* ptr = mat->data.fl + row*mat->step/4; 
        for( int col=0; col<mat->width; col++ ) 
            s += *ptr++;
    }
    return( s );
};

//快速访问图像数据,设置每个点的饱和度和高度
//imageData:指向第一行图像数据的指针
//imageData是cvMat与IplImage重要区别,imageData指针是字节类型uchar*,cvmat不一定。
void saturate_sv(IplImage* img) 
{
    for(int y=0; y<img->height; y++) 
    {
        uchar* ptr = (uchar*)(img->imageData + y*(img->widthStep));
        for(int x=0;x<(img->width);x++) //img->width:每行像素个数
        {
            ptr[3*x+1] = 128; //输入为3通道RGB图像、设置饱和度和高度值
            ptr[3*x+2] = 128;
        }
    }
}


效果图:




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值