【学习笔记】OpenCV+C++(六)

图像金字塔
       图像金字塔概念:
             我们在图像处理中常常会调整图像大小,最常见的就是放大(zoom in)和缩小(zoom out),尽管集合变换也可以实现图像放大和缩小,但是这里我们介绍图像金字塔
             一个图像金字塔式一系列的图像组成,最底下一张是图像尺寸最大,最上方的图像尺寸最小,从空间上从上向下就像一个古代的金字塔
          高斯金字塔---用来对图像进行降采样
              高斯金字塔从底向上,逐层降采样得到
              降采样之后图像大小是原图像MxN的M/2*N/2,就是源图像删除偶数行和列,即得到降采样之后上一层的图片
              高斯金字塔的生成过程分为两步
                  对当前层进行高斯模糊
                  删除当前层的偶数行和列
                即可得到上一层的图像,这样上一层跟下一层相比,都只有它的1/4大小
                      1  4  6  4  1
                1/16  4  16 24 16 4
                      6  24 36 24 6
                      4  16 24 16 4
                      1  4  6  4  1
            高斯不同(Difference of Gaussian - DOG)
                定义:就是把同一张图像在不同的参数下做高斯模糊之后的结果相减,得到的输出图像。称为高斯不同(DOG)
                高斯不同是图像的内在特征,在灰度图像增强、焦点检测中经常用到

          拉普拉斯金字塔---用来重建一张图片根据它的上层降采样图片
          采样相关API
              上采样(cv::pyrUp) - zoom in 放大
              降采样(cv::pyrDown) - zoom out缩小
              pyrUp(Mat src,Mat dest,Size(src.cols*2,src.rows*2))生成的图像是原图在宽和高各放大两倍

              pyrDown(Mat src,Mat dest,Size(src.cols/2,src.rows/2));生成的图像是原图在宽和高各缩小两倍
        高斯金字塔代码演示:

 #include<opencv2/opencv.hpp>
           #include<iostream>
           #include"math.h"
           using namespace cv;
           int main(int argc,char** argv){
               Mat src,dst;
               src = imread("");
               if(!src.data){
                   printf("could not load image...\n");
                   return -1;
               }
               char INPUT_WIN[] = "input image";
               char OUTPUT_WIN[] = "output image";
               namedWindow(INPUT_WIN,CV_WINDOW_AUTOSIZE);
               namedWindow(OUTPUT_WIN,CV_WINDOW_AUTOSIZE);
               imshow(INPUT_WIN,src);

               //上采样
               pyrUp(src,dst,Size(src.cols*2,src.rows*2));
               imshow(OUTPUT_WIN,dst);

               //降采样
               Mat s_down
               pyrDown(src,s_down,Size(src.cols/2,src.rows/2));
               imshow(OUTPUT_WIN,s_down);

               //DOG 高斯不同
               Mat g1,g2,gray_src,dogImg;
               cvtColor(src,gray_src,CV_BGR2GRAY);
               GaussianBlur(gray_src,g1,Size(3,3),0,0);
               GaussianBlur(g1,g2,Size(3,3),0,0);
               subtract(g1,g2,dogImg,Mat());
               normalize(dogImg,dogImg,255,0,NORM_MINMAX);
               imshow("DOG Image",dogImg);

               waitKey(0);
               return 0;

           }

基本阈值操作
    图像阈值(threshold)
        阈值是什么?简单点说是把图像分割的标尺,这个标尺是根据什么产生的,阈值产生算法?阈值类型。(Binary segmentation)

      阈值类型---阈值二值化(threshold binary)
          左下方的图表示图像像素点Src(x,y)值的分布情况,蓝色水平线表示阈值

          dst(x,y) = MaxVal  ifsrc(x,y)>thresh
                   = 0       otherwise

             ---阈值反二值化(threshold binary Inverted)
             dst(x,y) = 0  ifsrc(x,y) > thresh
                      = maxVal  otherwise

            ---截断(truncate)
              dst(x,y) =  threshold ifsrc(x,y)>thresh
                       =  src(x,y)   othrewise


            ---阈值取零(threshold to zero)
               dst(x,y) = src(x,y)  ifsrc(x,y) > thresh
                        = 0    otherwise


            ---阈值反取零(threshold to zero inverted)
                dst(x,y) = 0  ifsrc(x,y) > thresh
                         = src(x,y)   otherwise

            ---THRESH_BINARY  阈值二值化
                  dst(x,y) = MaxVal  ifsrc(x,y)>thresh
                   = 0       otherwise
            ---THRESH_BINARY_INV 阈值反二值化
                   dst(x,y) = 0  ifsrc(x,y) > thresh
                      = maxVal  otherwise
            ---THRESH_TRUNC  截断
                 dst(x,y) =  threshold ifsrc(x,y)>thresh
                       =  src(x,y)   othrewise

            ---THRESH_TOZERO  阈值取零
                 dst(x,y) = src(x,y)  ifsrc(x,y) > thresh
                        = 0    otherwise
            ---THRESH_TOZERO_INV  阈值反取零
                 dst(x,y) = 0  ifsrc(x,y) > thresh
                         = src(x,y)   otherwise


            ---THRESH_MASK
            ---THRESH_OTSU  flag,use Otsu algorithm to choose the optimal threshold value
            ---THRESH_TRIANGLE flag,use Triangle algorithm to choose the optimal threshold value

代码演示:

   #include<opencv2/opencv.hpp>
        #include<iostream>
        #include<math.h>
        using namespace cv;
        Mat src,dst,gray_src;
        int threshold_value = 127;
        int threshold_max = 255;
        int type_value = 2;
        int type_max = 5;
        const char* output_title = "binary image";
        void Threshold_Demo(int,void*);
        int main(int argc,char** argv){
            src = imread("");
            if(!src.data){
                printf("could not load image...\n");
                return -1;
            }
            namedWindow("input image",CV_WINDOW_AUTOSIZE);
            namedWindow(output_title,CV_WINDOW_AUTOSIZE);
            imshow("input image",src);

            createTrackbar("THRESHOLD VALUE",output_title,&threshold_value,threshold_max,Threshold_Demo);
            createTrackbar("Type Value",output_title,&type_value,type_max,Threshold_Demo);
            Threshold_Demo(0,0);


            while(true){

            }


            waitKey(0);
            return -1;
        }
        void Threshold_Demo(int,void*){
            cvtColor(src,gray_src,CV_BGR2GRAY);
            printf("%d",THRESH_BINARY);
            printf("%d",THRESH_BINARY_INY);
            printf("%d",THRESH_TRUNC);
            printf("%d",THRESH_THZERO);
            printf("%d",THRESH_TOZERO_INY);
            threshold(gray_src,dst,threshold_value,threshold_max,THRESH_BINARY);
            //threshold(gray_src,dst,threshold_value,threshold_max,type_value);
            //threshold(gray_src,dst,0,255,THRESH_OTSU | type_value);//自动计算阈值
            //threshold(gray_src,dst,0,255,THRESH_TRIANGLE | type_value);//三角法找阈值
            imshow(output_title,dst);
        }

自定义线性滤波
        卷积概念
           卷积是图像处理中一个操作,是kernel在图像的每个像素上的操作
        kernel本质上一个固定大小的矩阵数组,其中心点称为锚点(anchor point)

        卷积如何工作
            把kernel放到像素数组之上,求锚点周围覆盖的像素乘积之和(包括锚点),用来替换锚点覆盖下像素点值称为卷积处理。数学表达如下:
              H(x,y) = exp(i=0,Mi-1)[exp(j=0,Mj-1)[I(x+i-ai,y+j-aj)K(i,j)]]

           卷积的作用
               模糊图像
               提取边缘
               进行图像锐化
        常见算子
           Robert算子
              x方向       y方向
              +1 0        0  +1
              0  -1       -1  0
           Sobel算子
            x方向       y方向
              -1 0 1      -1 -2 -1
              -2 0 2      0   0  0
              -1 0 1       1  2  1
           拉普拉斯算子
               0 -1 0
               -1 4 -1
               0 -1 0
        自定义卷积模糊
           filter2D方法
           filter2D(
              Mat src,//输入图像
              Mat dst,//模糊图像
              int depth,//图像深度32/8
              Mat kernel,//卷积核/模板
              Point anchor,//锚点位置
              double delta//计算出来的像素+delta
           )其中kernel是可以自定义的卷积核
        代码演示:

  #include<opencv2/opencv.hpp>
            #include<iostream>
            #include<math.h>

            using namespace cv;
            int main(int argc,char** argv){
                Mat src,dest;
                Mat kernel;
                int ksize = 0;
                src = imread("");
                if(!src.data){
                    printf("could not load image...\n");
                    return -1;
                }
                char INPUT_WIN[] = "input image";
                char OUTPUT_WIN[] = "result image";
                namedWindow(INPUT_WIN,CV_WINDOW_AUTOSIZE);
                namedWindow(OUTPUT_WIN,CV_WINDOW_AUTOSIZE);

                imshow(INPUT_WIN,src);

                //Robert算子 x方向
                Mat kernel_x = (Mat_<int>(2,2)<<1,0,0,-1);
                filter2D(src,dst,-1,kernel_x,Point(-1,-1),0.0);
                //Robert算子  y方向
                Mat kernel_y = (Mat_<int>(2,2)<<0,1,-1,0);
                filter2D(src,dst,-1,kernel_y,Point(-1,-1),0.0);

                waitKey(0);
                return 0;
            }
发布了9 篇原创文章 · 获赞 1 · 访问量 144

猜你喜欢

转载自blog.csdn.net/Qsouler/article/details/104216364