计算机视觉与图像处理(一)——卷积与opencv

一、摄像机与视频的读取


 VideoCapture cap(0);        //打开默认摄像头设备
                             //1.VideoCapture cap(in device);  如果只有一个设备,device只通过0  
                             //2.VideoCapture cap(const string& filename); filename为要打开的视频文件名

    while (true)
    {
        Mat frame;          
        cap>>frame;         //从摄像头得到一个新的帧

        namedWindow("123",0);//创建一个名为 123 的窗口
                             /*
                             void namedWindow(const string& winname,int flags); 
                             参数一,const string&型的name,即填被用作窗口的标识符的窗口名称。
                             参数二,窗口标识flags,可取值:(1)WINDOW_AUTOSIZE,窗口大小会自动调整以适应所显示的图像,且不能手动改变
                                                            (2)WINDOW_NORMAL,用户可任意改变窗口大小
                                                            (3)WINDOW_OPENGL,所创建窗口支持OpenGL
                                     PS:flasgs项不填时默认其值为WINDOW_AUTOSIZE
                             */
        imshow("123",frame); //在指定的窗口 123 中显示一幅图像 
                             /*
                             void imshow(const string& winname, InputArray mat); 
                             参数一,winname,填需要显示的窗口标识名称
                             参数二,InputArray 类型的mat,填需要显示的图像
                             */
                             
        waitKey(30);    //每处理完一帧,程序会等待30毫秒才会读取下一帧
                        /*
                        waitKey(delay);
                        delay>0,每处理完一帧,程序会等待delay毫秒才会读取下一帧
                        delay=0,只会显示第一帧视频
                        */
        
    }

二、读取图片 与其中的像素值


    Mat img_origin=imread("123.jpg",1);       //读入三通道彩色图像 123
                                              /*
                                              Mat imread(const string& filename, intflags=1 );
                                              flags>0或flags=CV_LOAD_IMAGE_COLOR,返回一个3通道的彩色图像。
                                              flags=0或flags=CV_LOAD_IMAGE_GRAYSCALE,返回灰度图像。
                                              flags<0,返回包含Alpha通道的加载的图像。
                                              flags=CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR,载入最真实的图像。
                                              */
    Mat img_gray;
    cvtColor(img_origin,img_gray,CV_RGB2GRAY); //转(123)彩色图像为灰色
                                                /*
                                                void cvtColor(InuputArray img_origin,OutputArray img_gray,int code,int dstCn=0); 
                                                img_origin,原始图像
                                                img_gray,更改后的目标图像
                                                code为一掩码,CV_RGB2GRAY为模式之一,功能:转彩色图像为灰色
                                                */

    cout<<(int)img_gray.at
  
  
   
   (1,1)<
   
   
  
  

三、Mat对象一些操作

    Mat imgone = Mat::ones(5,5,CV_64FC1);    //建立5行5列零矩阵
    Mat imgzero = Mat::zeros(5,5, CV_64FC1); //建立5行5列且所有元素均为1的矩阵    
    Mat image = Mat::eye(5,5,CV_64FC1);      //建立单位阵(主对角线元素均为1)
                                            /* 初始化函数cv::Mat::zeros , cv::Mat::ones , cv::Mat::eye 指定要使用的大小和数据类型*/         
    Mat sum = image+imgone;  //矩阵求和
    cout<
      
      
       
       <
       
       
      
      
四、图像x方向求导的卷积与非卷积操作

VideoCapture cap(0);
    while (true)
    {
        Mat frame;
        cap>>frame;           //读入原图像

        cvtColor(frame,frame,CV_RGB2GRAY);

        /*非卷积*/
        Mat dimg=Mat(frame.rows,frame.cols-2,CV_8UC1);  //初始化单通道的目标图像,x方向求导,故比原图像少两列
        /*直接将原图像操作矩阵中要产生新像素值的方格左右两侧元素相减,产生目标图像新像素点*/
        for (int i=0;i
        
        
         
         (i,j-1)=frame.at
         
         
          
          (i,j-1)-frame.at
          
          
           
           (i,j+1);
            }
        }*/
        
        /*卷积*/
        Mat dimg=Mat(frame.rows,frame.cols-2,CV_8UC1);    //在x方向对原图像的卷积操作不处理边界,故产生的目标图像比原图像少两列
        Mat model=Mat(1,3,CV_64FC1);         //建立1行3列的模板
        /*初始化模板*/
        model.at
           
           
            
            (0,0)=1;             
        model.at
            
            
              (0,1)=0; model.at 
             
               (0,2)=-1; /*具体卷积操作*/ /*1.卷积操作数矩阵与模板矩阵中对应位置元素相乘求和,产生目标图像的一个像素点*/ /*2.在x方向进行平移,重复操作1,直到处理完原图像*/ for(int i=0;i 
              
                (i+m,j+n))*model.at 
               
                 (m,n+half); } } dimg.at 
                
                  (i,j-1)=(uchar)sum; } } imshow("123",dimg); waitKey(10); } 
                 
                
               
              
            
           
           
          
          
         
         
        
        
五、高斯模糊的核创建与卷积操作

 (一)高斯模糊原理
所谓"模糊",即每一个像素都取周边像素的平均值。
上图中,2是中间点,周边点都是1。"中间点"取"周围点"的平均值,就会变成1。在数值上,这是一种"平滑化"。在图形上,就相当于产生"模糊"效果,"中间点"失去细节。
计算平均值时,取值范围越大,"模糊效果"越强烈。
每个点都要取周边像素的平均值,如果使用简单平均,显然不是很合理,因为图像都是连续的,越靠近的点关系越密切,越远离的点关系越疏远。因此,加权平均更合理,距离越近的点权重越大,距离越远的点权重越小。
(二)正态分布的权重

正态分布显然是一种可取的权重分配模式。在图形上,正态分布是一种钟形曲线,越接近中心,取值越大,越远离中心,取值越小。计算平均值的时候,我们只需要将"中心点"作为原点,其他点按照其在正态曲线上的位置,分配权重,就可以得到一个加权平均值。          

(三)高斯函数

一维:

二维


利用函数计算每个点的权重计算高斯模糊( 由高斯函数计算出每个点的权重值,即得到权重矩阵)

(四)计算高斯模糊

   1. 对权重矩阵做归一化处理
(1)求出权重矩阵中所有权重之和,
(2)每个点都除以权重之和,使权重之和为一。
   2. 计算高斯模糊的值。假设现有9个像素点,每个点灰度值乘以自己的权重值,得到9个值,将这9个值加起来,就是中心点的高斯模糊的值。对所有点重复这个过程,得到高斯模糊后的图像。
PS:如果原图是彩色图片,可以对RGB三个通道分别做高斯模糊。

(五)代码实现
 double sigma=50;
    Mat gauss(5,5,CV_64FC1);
    for (int i=-2;i<3;i++)
    {
        for (int j=-2;j<3;j++)
        {
            gauss.at
        
        
         
         (i+2,j+2)=exp(-(i*i+j*j)/(2*sigma*sigma)); /*利用二维高斯函数计算每个点的权重*/
        }
    }

    double gssum=sum(gauss).val[0];   /*求权重之和*/
    /*权重矩阵做归一化处理*/
    for (int i=-2;i<3;i++)
    {
        for (int j=-2;j<3;j++)
        {
            gauss.at
         
         
          
          (i+2,j+2)/=gssum;  /*每个点都除以权重之和,使权重之和为1*/
        }
    }

    //cout<
          
          
           
           <
           
           
            
            >frame;
        cvtColor(frame,frame,CV_RGB2GRAY);
        Mat dimg=Mat(frame.rows-4,frame.cols-4,CV_8UC1);
        /*图像卷积操作,无边缘处理*/
        for (int i=2;i
            
            
              (i+m-2,j+n-2))*gauss.at 
             
               (m,n); } } dimg.at 
              
                (i-2,j-2)=(uchar)sum; } } imshow("a",frame); imshow("gauss",dimg); waitKey(10); } 
               
              
            
           
           
          
          
         
         
        
        

六、相关API操作


    VideoCapture cap(0);
    while (true)
    {
        Mat frame;
        cap>>frame;
        cvtColor(frame,frame,CV_RGB2GRAY);

        GaussianBlur(frame,frame,cvSize(5,5),10,10);   //调用高斯模糊函数,对图像平滑(模糊)处理
        //Canny(frame,frame,100,100);   //边缘检测(1.去噪即对原图像或高斯平滑模板做卷积2.寻找图像中的亮度梯度3.跟踪边缘)
        //Sobel(frame,frame,0,1,1);  //计算图像亮度函数的一阶梯度矢量或法矢量(PS:常用于边缘检测)

        imshow("q",frame);
        waitKey(10);

    }


参考资料:http://www.ruanyifeng.com/blog/2012/11/gaussian_blur.html
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值