002.叶欣机器视觉学习笔记_第二课_图像的预处理部分

图像预处理

1.图像显示与存储原理

a.RGB颜色空间

b.CMY(K)颜色空间

c.HSV颜色空间(人眼)

  • 第二课 00:06:38

  • 人眼视觉概念

    • H/Hue:色调,颜色种类
    • S/Saturation:饱和度,颜色的纯度
    • V/Value:明度,颜色的明亮度
  • 一个像素用(h,s,v)表示,并且可以转化为RGB

d.CIE-XYZ最精确的颜色空间

  • 第二课 00:07:28

f.RGB三通道转灰度图单通道公式

  • Gray = R*0.3 + G*0.59 + B*0.11

2.图像增强的目标

a.目的:实现锐化,平滑,去噪,对比度增强

b.图像处理

i:空间域处理

一. 点运算(HE,AHE,CLAHE)
  • 基于直方图(Histogram)统计,直方图越宽胖,肉眼可见暗部细节就越多

  • x轴:像素区间, y轴:落在该区间的像素的个数 (第二课 00:16:13)

  • 直方图均衡化(HE)可以调整图像对比度

    • 就是把"瘦高的直方图"拉成"胖矮直方图"(第二课 00:19:38)

    • 比如像素127127和像素128128靠的太近,肉眼无法分辨出来,就需要一个函数把127127变成140140,把128128变成180180,这样肉眼就可以分辨出来了,当然,要求原本比rr暗的像素,在变换后依然比ss暗(原本比rr亮的像素,在变换后依然比ss亮),才不至于黑白颠倒

    • 直方图均衡化灰度转换函数推导博客https://blog.csdn.net/superjunenaruto/article/details/80037777

    • 使用累积分布函数 作为映射函数T()T(),使得图像映射后更分散

      • 累积分布函数性质

        • 单调递增(可以保证比rr亮的像素,T()T()映射后还是比rr

        • 值域为0011,(控制像素变换后依然在[0,255][0,255]范围内)

        • 累积分布函数公式为:Tk=j=0k=256个像素count像素值,k=0,1,2,3...255T_{k}=\sum_{j=0}^{k=共256个像素} \frac{count_{像素值}}{长*宽},k=0,1,2,3...255

          注意:每一个像素rr都对应一个不同的TT

      • 某个像素sis_i的计算公式:si=(2550)(像素i的累积概率Ti)s_i=(255-0)*(像素i的累积概率T_i)

        波峰和前后两个像素 像素出现的概率 累积概率 映射后
        像素(r1)(r-1) 0.010.01 0.090.09 (2550)0.09=22.9(255-0)*0.09=22.9
        像素rr 0.010.01 0.100.10 (2550)0.10=25.5(255-0)*0.10=25.5
        像素(r+1)(r+1) 0.010.01 0.110.11 (2550)0.11=28.0(255-0)*0.11=28.0
    • 优缺点:

      • 优点:

        1. 无参数的优化对比度算法,免去了针对不同图像进行调整的过程
        2. 处理后像素值几乎均匀分布
      • 缺点:

        • 缺点1:如果图像中有明显亮(或明显暗)的区域,则作用有限,变得更亮(或更暗)的地方可能会丢失细节
        • 缺点2:噪点会被放大
    • 问题:

      1. 离散型由于取整,导致出现多对一的映射关系。比如把像素128和像素130映射后得到T(120)=131.25T(125)=131.94,由于我们取整,得到两个都是131,这就使得图像不平坦。
      2. 直方图均衡只能使用一次,多了也没什么效果
      3. 直方图均衡可以通过直方图匹配(直方图规定化)来实现,matlab里就是这样的。
  • 自适应直方图均衡(AHE Adaptive)

    • 就是把图片横着切几刀,竖着切几刀,再对每个子块做HE,最后拼起来

    • 缺点:图片会产生明显的分割线

  • 限制对比度自适应直方图均衡化(CLAHE)

    • 直方图等面积变换:可以让对比度更自然

    • 什么是双线性插值

      • 百度百科:如图,已知4个红点Q,如何求绿点P的坐标?

        先在两条横线中插入R1R2R_1和R_2,再对竖线R1,R2(R_1,R_2)中插入PP

    • 缺点:

      • 缺点1:本来比较均匀的区域,会把噪声放大了
    • 应用:图像去雾

    • 第二课 00:21:32截图

  • opencv中使用clahe

    void opencvEqualizeHist_CLAHE() {
        using namespace cv;
        Mat img, img_gray, result;
        Mat clahe_result;
        img = imread("/media/majiao/Elements/majiao/尼康1j1/2022_09_10中秋学校拍的/DSC_0308.JPG");
        int wid = img.cols*0.2, hei = img.rows*0.2;
    
        resize(img, img, cv::Size(wid, hei));
        cvtColor(img, img_gray, cv::COLOR_BGR2GRAY);
        equalizeHist(img_gray, result);
    
        cv::Ptr<CLAHE> clahe = cv::createCLAHE();
        clahe->setClipLimit(4);
        clahe->setTilesGridSize(cv::Size(10, 10));
        clahe->apply(img_gray, clahe_result);   
        imshow("src", img_gray); 
        imshow("result", result); 
        imshow("clahe_result", clahe_result); 
        waitKey();
    }
    


二.形态学运算(膨胀,腐蚀)第二课 29:57:00
  1. 膨胀(dilate达累特)

    • 目的:消除噪声,连接图像中相邻的元素

    • 膨胀就是局部求最大值,公式为新图像i,j=max核中所有1(kenel1与原图重合的像素值)新图像素_{i,j}=max_{核中所有1}({kenel的1与原图重合的像素值})

      原图中间不连续(T的连接处断开了)
         0,   0,   0,   0,   0,   0,   0,   0,   0,   0;
         0,   0,   0,   0,   0,   0,   0,   0,   0,   0;
         0,   0,   0,   0,   0,   0,   0,   0,   0,   0;
       255, 255, 255, 255, 255, 255, 255, 255, 255, 255;
         0,   0,   0,   0,   0,   0,   0,   0,   0,   0;
         0,   0,   0,   0,   0, 255,   0,   0,   0,   0;
         0,   0,   0,   0,   0, 255,   0,   0,   0,   0;
         0,   0,   0,   0,   0, 255,   0,   0,   0,   0;
         0,   0,   0,   0,   0, 255,   0,   0,   0,   0;
         0,   0,   0,   0,   0, 255,   0,   0,   0,   0]
      
      经过cv::dilate膨胀后,就相连了
         0,   0,   0,   0,   0,   0,   0,   0,   0,   0;
         0,   0,   0,   0,   0,   0,   0,   0,   0,   0;
       255, 255, 255, 255, 255, 255, 255, 255, 255, 255;
       255, 255, 255, 255, 255, 255, 255, 255, 255, 255;
       255, 255, 255, 255, 255, 255, 255, 255, 255, 255;
         0,   0,   0,   0, 255, 255, 255,   0,   0,   0;
         0,   0,   0,   0, 255, 255, 255,   0,   0,   0;
         0,   0,   0,   0, 255, 255, 255,   0,   0,   0;
         0,   0,   0,   0, 255, 255, 255,   0,   0,   0;
         0,   0,   0,   0, 255, 255, 255,   0,   0,   0]
      

  2. 腐蚀(erode衣肉的)割出图像中独立的元素

    • 腐蚀:就是局部求最小值,公式新图像i,j=min核中所有1(kenel1与原图重合的像素值)新图像素_{i,j}=min_{核中所有1}(kenel的1与原图重合的像素值)
  3. 在opencv中使用腐蚀膨胀函数

    void opencvErodeDilateTest() {
        using namespace cv;
        Mat img, img_gray, result;
        Mat clahe_result;
        img = imread("/home/majiao/图片/p2235240978.jpg");
        int wid = img.cols*0.2, hei = img.rows*0.2;
    
        resize(img, img, cv::Size(wid, hei));
        cvtColor(img, img_gray, cv::COLOR_BGR2GRAY);
    
        cv::Mat img_erode, kenel = Mat::ones(3, 3, img_gray.type());
                           /**
                            * kenel为3x3的全1矩阵
                            *     1  1  1
                            *     1  1  1
                            *     1  1  1
                            */
        cv::erode(img_gray, img_erode, kenel); // 腐蚀
    
        cv::Mat img_dilate;
        cv::dilate(img_gray, img_dilate, kenel); // 膨胀
    
        cv::Mat kenel2 = getStructuringElement( /* 生成核 */
                                               cv::MORPH_RECT, /* 可选  cv::MORPH_CROSS 十字型 
                                                                       cv::MORPH_OPEN 开运算
                                                                       cv::MORPH_CLOSE 闭运算
                                                                       cv::MORPH_GRADIENT 形态学梯度
                                                                       cv::MORPH_TOPHAT 顶帽
                                                                       cv::MORPH_BLACKHAT 黑帽
                                                                       cv::MORPH_ERODE 腐蚀
                                                                       cv::MORPH_DELATE 膨胀
                                                               */
                                               cv::Size(3, 3));
        cv::Mat img_dilate_morph_rect; cv::dilate(img_gray, img_dilate_morph_rect, kenel2);
    
        imshow("img_gray", img_gray);
        imshow("erode_3x3", img_erode);
        imshow("dilate_3x3", img_dilate);
        imshow("img_dilate_morph_rect", img_dilate_morph_rect);
        std::cout << kenel << std::endl;
        std::cout << kenel2 << std::endl;
        waitKey();
    }
    

开运算:先腐蚀再膨胀,可以去掉目标外的孤立点

闭运算:先膨胀再腐蚀,可以去掉目标的孔洞

三.临域运算(卷积,金字塔)
1.卷积(也叫滤波)
a. 卷积定义:对应位置相乘再相加
  1. 冈萨雷斯书上的卷积公式:
    image
    中科院王伟强老师说这个不应该叫卷积,应该叫相关
  2. 需要理解什么是线性移不变系统
    1. 线性,只有加法和乘法
b. Padding(边界填充):
  • 卷积完,新图可能会小一点,为了使得新图和原图一样大,所以一般用0填充边界后再卷积,卷积核越大则填充越多
  • 尽量不要用大卷积核去卷小图,因为用0来padding会影响新图的结果
d. 卷积分解特性(级联高斯)
  • 结论:如果一个卷积核可以表达成水平核H竖值核V相乘,则这个卷积核是可分离的

  • 对称2D卷积拆分成2个相同的1D卷积(行与列),注意要对称

    • 拆分后计算量下降:2D卷积K*K次计算,1D卷积只要2K次计算

    • 第二课00:48:00截图

    • TEST_CASE("test_opencv_卷积操作_002_filter2D卷积核2D分解为1D降低计算量", "[test_opencv_convolution]") {
          Mat img, img_gray, result;
          Mat clahe_result;
          img = imread(test_opencv_convolution_kenels::imagePath);
          int wid = img.cols*0.2, hei = img.rows*0.2;
      
          resize(img, img, cv::Size(wid, hei));
          cvtColor(img, img_gray, cv::COLOR_BGR2GRAY);
          
          cv::Mat kernel2D = (Mat_<uchar>(3,3) <<    1, 2, 1, // 2D核心:可以写成行列相乘的形式
                                                     2, 4, 2,
                                                     1, 2, 1); 
          cv::Mat kernel2DRow = (Mat_<uchar>(1,3) << 1, 2, 1); // 1D核心行
          cv::Mat kernel2DCol = (Mat_<uchar>(3,1) << 1, 2, 1); // 1D核心列
          cv::Mat src = (Mat_<uchar>(5,5) << 2,3,4,5,6,
                                             3,4,5,6,7,
                                             3,4,5,6,7,
                                             3,4,5,6,7,
                                             3,4,5,6,7);
          cv::Mat dst, dst2;
          cv::filter2D(src, dst, 0, kernel2D);        /*直接卷2D核心*/
          { cv::filter2D(src, dst2, 0, kernel2DRow);  /*先卷行*/
            cv::filter2D(dst2, dst2, 0, kernel2DCol); /*再卷列*/}
      }
      
f. 卷积的性质:
  • 交换律:fg=gff卷g=g卷f
  • 结合律:fg)卷h=f卷(gh(f卷g)卷h=f卷(g卷h)
  • 分配率:f(g+h)=(fg)+(fh)f卷(g+h)=(f卷g)+(f卷h)
  • 数乘:a(fg)=(af)g=f(ag)a(f卷g)=(af)卷g=f卷(ag)
g.卷积convolution的由来
h. opencv里的卷积函数cv::filter2D(src, dst, ddepth, kernel)
i. 低通滤波器与高通滤波区别
  1. 人眼对高频信息更敏感,(白纸上有一行字,我们肯定直接聚焦在这行字上,而不是白纸上)
  2. 图像上,变化剧烈的地方是高频信号,变化平缓的地方是低频信号

= 常用卷积核
  • 001.平滑均值滤波: 参数和为1,用来去除噪声,但效果不好(破坏了细节,无法去除椒盐噪声)没什么人用

    优点:平滑图像,降低锐度,模糊图像并去除噪声

    缺点:对椒盐噪声基本无能为力,

    TEST_CASE("test_opencv_卷积核测试_001_均值滤波器", "[test_opencv_convolution_kenels]") {
        Mat img, img_gray, result;
        Mat clahe_result;
        img = imread(test_opencv_convolution_kenels::imagePath);
        int wid = img.cols*0.2, hei = img.rows*0.2;
    
        resize(img, img, cv::Size(wid, hei));
        cvtColor(img, img_gray, cv::COLOR_BGR2GRAY);
        cv::Mat img_bulr; 
        cv::blur(img_gray, img_bulr, cv::Size(3,3)); /**
                                                      bulr 平滑均值滤波 
                                                           作用 : 1.平滑图像,降低锐度
                                                                  2.模糊图像并去除噪声
                                                           缺点 : 去噪效果差,破坏了细节,
                                                                  椒盐噪声几乎没法去除
                                                                1  1  1
                                                        1/9  x  1  1  1
                                                                1  1  1
                                                     */
        imshow("灰度图src", img_gray);
        imshow("经过bulr均值滤波后", img_bulr);
        waitKey();
    }
    

  • 002.平滑中值滤波:卷积域内的像素值排序后取中间值输出

    • 优点:
      1. 有效去除椒盐噪声(椒盐就是图像上的白点或黑点)
    • 缺点:
      1. 可能会删除图像中非线性的部分,冈萨雷斯第四版131页,pdf第146页,医学影像最好别用

    TEST_CASE("test_opencv_卷积核测试_002_中值滤波MedianFilter", "[test_opencv_convolution_kenels]") {
        Mat img, img_gray, result;
        Mat clahe_result;
        img = imread(test_opencv_convolution_kenels::imagePath);
        int wid = img.cols*0.2, hei = img.rows*0.2;
    
        resize(img, img, cv::Size(wid, hei));
        cvtColor(img, img_gray, cv::COLOR_BGR2GRAY);
        for (int i=0; i+10<img_gray.cols; i+=10) { // 撒上椒盐噪声
            for (int j=0; j+10<img_gray.rows; j+=10) {
                if (i < img_gray.rows && j < img_gray.cols)
                    img_gray.at<uchar>(i, j) = 0;
            }
        }
        
        cv::Mat img_median; 
        /* 中值滤波 : 卷积域的像素值排序后取中间值输出为新像素
           优点     : 有效去除椒盐噪声 */
        cv::medianBlur(img_gray, img_median, 3/*模糊核的线性大小3,5,7...*/);
        
        imshow("灰度图src", img_gray);
        imshow("经过medianBlur中值滤波后", img_median);
        waitKey();
    }
    

  • 003.高斯滤波(重要):模拟人眼关注中心区域,应用于高斯金字塔

    • 第二课:44:28

    • 高斯分布公式:Gσ=12πσ2ex2+y22σ2G_\sigma={\frac{1}{2*\pi*\sigma^2}}*e^{-\frac{x^2+y^2}{2*\sigma^2}},入参σ\sigma标准差,标准差增大,图像变矮

      如图:卷积后会突出中心点的像素,中心点附近的像素也会或多或少算进去

    • 且高斯核具有可分离性,2D可以分解为2个1D的核

      TEST_CASE("test_opencv_卷积核测试_003_高斯滤波GuassianFilter", "[test_opencv_convolution_kenels]") {
          Mat img, img_gray, result;
          Mat clahe_result;
          img = imread(test_opencv_convolution_kenels::imagePath);
          int wid = img.cols*0.2, hei = img.rows*0.2;
      
          resize(img, img, cv::Size(wid, hei));
          cvtColor(img, img_gray, cv::COLOR_BGR2GRAY);
          /** 高斯滤波:模拟人眼,突出中间点,图像是正态分布的3维版本 */
          cv::Mat img_gaussian_sigma_0_1, img_gaussian_sigma_1, 
                  img_gaussian_sigma_3, img_gaussian_sigma_7; 
          cv::GaussianBlur(img_gray, img_gaussian_sigma_0_1, cv::Size(7,7), 0.1);
          cv::GaussianBlur(img_gray, img_gaussian_sigma_1, cv::Size(7,7), 1);
          cv::GaussianBlur(img_gray, img_gaussian_sigma_3, cv::Size(7,7), 3);
          cv::GaussianBlur(img_gray, img_gaussian_sigma_7, cv::Size(7,7), 7/*sigmaX越大越模糊*/);
      }
      
    • 应用

      1. 高斯滤波消除图像中的阴影(阴影校正): 在冈萨雷斯第四版115页,pdf第130页​
        drawing
  • 004.prewitt水平或垂直边缘滤波器(常用改进后的sobel算子)

    •   水平边缘                竖值边缘滤波    
         1   1   1                -1  0  1       -1  -1  0        0  1  1
         0   0   0                -1  0  1       -1   0  1       -1  0  1
        -1  -1  -1                -1  0  1        0   1  1       -1 -1  0
        可分解为行(1,1,1)和列(1,0,-1) 
      
    •   TEST_CASE("test_opencv_卷积核测试_004_Prewitt水平或垂直滤波器01", "[test_opencv_convolution_kenels]") {
            Mat img, img_gray, result;
            Mat clahe_result;
            img = imread(test_opencv_convolution_kenels::imagePath);
            int wid = img.cols*0.2, hei = img.rows*0.2;
      
            resize(img, img, cv::Size(wid, hei));
            cvtColor(img, img_gray, cv::COLOR_BGR2GRAY);            
                                                                    
            cv::Mat kernelV = (Mat_<float>(3,3) <<  -1,  0,  1,     
                                                    -1,  0,  1,     
                                                    -1,  0,  1 );   
                                           //        -1   0   1  [水平梯度/垂直边缘]
                                           //     -------------  可分解成水平(-1,0,1)
                                           //  1  |  -1,  0,  1  和竖直(1,1,1)
                                           //  1  |  -1,  0,  1
                                           //  1  |  -1,  0,  1
                                                                    
            cv::Mat kernelH = (Mat_<float>(3,3) <<  -1, -1, -1,     
                                                     0,  0,  0,     
                                                     1,  1,  1);    
                                          //         1   1   1  [垂直梯度/水平边缘]
                                          //     -------------  可分解成水平(1,1,1)
                                          //  -1 |  -1, -1, -1  和竖直(-1,0,1)
                                          //   0 |   0,  0,  0
                                          //   1 |   1,  1,  1
            cv::Mat after_prewittV, after_prewittH;
            cv::filter2D(img_gray, after_prewittV, -1, kernelV); 
            cv::filter2D(img_gray, after_prewittH, -1, kernelH); 
            Mat prewitt_HV = after_prewittH + after_prewittV;
            imshow("灰度图src",  img_gray);
            imshow("prewitt垂直边缘算子后", after_prewittV);
            imshow("prewitt水平边缘算子后", after_prewittH);
            imshow("prewitt横竖相加", prewitt_HV);
            waitKey();
        }
      
  • 005.Sobel边缘过滤算子(分为x方向和y方向)

    • 梯度密不可分,本质上是梯度运算,可以和杨辉三角对应上

    • 对图像中弱边缘提取效果差(可用Scharr算子替代)

    • 产生梯度的情况

    • 中心点p5的梯度如何求

    • sobel的本质是一阶导数https://blog.csdn.net/lz0499/article/details/118003220

    • Roberts算子只考虑了差分,prewitt也是一阶差分且引入了均值,sobel兼顾了差分和类似高斯的平滑处理,[1,0,-1]及其转置分别代表水平差分和垂直差分,[1,2,1]则类似高通平滑过滤噪声

    • Sobel的构造方法

      • opencv里的getSobelKernels函数会返回x方向和y方向的1x3Sobel算子 (3x3分解后的)
      • NNNN列的Sobel类似高斯平滑的部分可以用杨辉三角的第N行构造,然后差分出下一行或下一列(减1或减2)
    • TEST_CASE("test_opencv_卷积核测试_005_Sobel边缘过滤算子_01水平和竖直", "[test_opencv_convolution_kenels]") {
          Mat img, img_gray, resultX, resultY, cvResultX, cvResultY;
          img = imread(test_opencv_convolution_kenels::imagePath);
          int wid = img.cols*0.2, hei = img.rows*0.2;
      
          resize(img, img, cv::Size(wid, hei));
          cvtColor(img, img_gray, cv::COLOR_BGR2GRAY);            
                                                                  
          cv::Mat kernelX = (Mat_<float>(3,3) <<   -1, -2,  1,     
                                                    0,  0,  0,     
                                                    1,  2,  1 );   
          cv::Mat kernelY = (Mat_<float>(3,3) <<   -1,  0,  1,     
                                                   -2,  0,  2,     
                                                   -1,  0,  1 );   
          cv::filter2D(img_gray, resultX, -1, kernelX); 
          cv::filter2D(img_gray, resultY, -1, kernelY); 
          cv::Sobel(img_gray, cvResultX, -1, 2, 0, 3); // 突出了竖线
          cv::Sobel(img_gray, cvResultY, -1, 0, 2, 3); // 突出了横线
          
            cv::getDerivKernels(kernelX, kernalY, 1, 0, FILTER_SCHARR=-1); 
          // ksize=-1时生成scharr核,否则都生成sobel核(可分离的行列核心)
          waitKey();
      }
      
    • 应用

      • 缺陷检测时,用来消除几乎没什么变化的背景,并且增强待检测物体的边缘。冈萨雷斯第四版125页,pdf第140页有一个检测眼镜片边缘磨损的例子。
      • 用来突出肉眼很难看到的细小物体,如保护液中的气泡,划痕
    • 问题:

    • 目标像素运算结果不在0到255区间内怎么办?

      • opencv里是直接截断,负数取0,大于255取255
      • 实际负数取绝对值,大于255取255,会比较合理
    • 总的梯度如何求?

      • 开根号[ (x方向梯度平方) + (y方向梯度平方) ]

        G=(Gx2+GY2)G_总=\sqrt{(G_x^2+G_Y^2)}{}

        或者用简化的梯度G=Gx+GyG_总=|G_x|+|G_y|

    • 冈萨雷斯第四版书中124页,pdf第139页中说:Sobel算子强调中心重要程度实现某种平滑,这里的某种平滑指的是什么?

    • 医学影像常用的图像处理策略有哪些?

      1. 如果噪声多,不建议用中值滤波,建议先使用拉普拉斯争强细节,再用sobel突出边缘。冈萨雷斯第四版129页,pdf第144页
  • 005.Scharr算子和sobel差不多(梯度检测中常用)

    •       3  10  3  其他方向都和sobel差不多
            0   0  0  只不过改成了3 10 3
           -3 -10 -3
              cv::getDerivKernels(kernelX, kernalY, 1, 0, FILTER_SCHARR=-1); 
             // ksize=-1时生成scharr核,否则都生成sobel核(可分离的行列核心)
      
      
  • 006.Laplacian算子过滤边缘(具有旋转不变性的算子之一)

    1. 在冈萨雷斯第四版119页,pdf第134页
      拉普拉斯算子对边缘敏感
    • 注意看算子加和等于零

    • 拉普拉斯算子是二阶导:
      1. f(x) = f(x-1)+f(x+1) - 2f(x) 左右之和减去2倍的中间像素
      2. f(y) = f(y-1)+f(y+1) - 2
      f(y) 上下之和减去2倍的中间像素
      3. 合并起来就是 f(x,y) = f(x-1,y)+f(x+1,y)+f(x,y-1)+f(x,y+1) - 4*f(x,y)

    • 增强对比度的方法:新图S = (原图A) 减 (laplacian卷一遍后的图B)

    • opencv中的cv::Laplacian竟然是用Sobel实现的

      • 如果卷积核用1x1或3x3就用上面的卷积,但是卷积核大于等于5x5就会使用sobel
      • 内部用了CV_OCL_RUN(ocl_Laplacian5(,,,)),优先使用openCL硬件和GPU运算
    • 计算图像模糊度,具体操作为:用图片的1个通道用以下3x3的核进行卷积,然后计算输出的方差,如果方差cv::meanStdDev小于一定值则图片视为模糊

    • 细节参考"./维基百科上对laplace的讲解Discrete_Laplace_operator_Wikipedia.pdf"

    • 问题

      1. 如何用opencv创建一个log算子,(类似于matlab的fspecial函数)?

ii:频率域处理

一.傅里叶变换
二.小波变换

iii:空间域要映射到频率域

  • 好处:可以快速计算卷积
  • 空间域上的卷积等于频率域上面的乘

3.点运算:基于直方图的对比度增强

4.形态学处理

5.空间域处理:卷积

6.卷积的应用:平滑,边缘检测,锐化等

锐化

锐化:补偿图像的轮廓,增强图像的边缘及灰度跳变的部分,使图像变得清晰的方法,也叫边缘增强

  1. 一个像素r,如果左边的像素减,右边的像素加,那对比度是不是就上来了!

1. 用钝化(平滑后的)图像来锐化

  1. 冈萨雷斯第四版122页,pdf138页,书上说20世纪30年代就有这种做法了(效果较差,现在用的少)
  2. 做法分3步:
    1. 先模糊原图,得到模糊图imgBlur
    2. 再用原图减去模糊图,得到模板图,即:模板图 = src - imgBlur
    3. 最后再把原图与模板图相加得到锐化图,即:img锐化 = src + 模板图

2. 用拉普拉斯滤波器进行锐化,g(x,y)=f(x,y)2f(x,y)g(x,y)=f(x,y)-▽^2f(x,y)

  1. 拉普拉斯算子是x和y两个方向上都是二阶导
  2. 就是锐化好的新图=原图-拉普拉斯卷积后的图,(原图减去拉普拉斯卷积后的图像)
                        | 0  1  0   |
       src - (src 卷积  | 1  -4  1   |  ) 
                        | 0  1  0   |
       锐化可以优化成下面这样 (直接拿原图卷这个核,省去了一个减法过程)
                   |   0  1  0  |
         src 卷积   |  1  -5  1  |
                   |   0  1  0  |
    

7.频率域处理:傅里叶变换,小波变换

8.应用案例

a.平滑,边缘检测,CLAHE等


补充

1. 卷积convolution的由来

知乎-动画理解卷积由来

a. 卷积公式:

  • 连续型:(fg)(n)=inf+inf[f(t)g(nt)dt](f*g)(n)=\int_{-inf}^{+inf}[{f(t)g(n-t)dt}]
  • 离散型:(fg)(n)=inf+inf[f(t)g(nt)](f*g)(n)=\sum_{-inf}^{+inf}{[f(t)g(n-t)]}

b. 卷积由来

  • 问题1:考虑两个骰子A和B,摇一次得到2个值A1和B1,定义sum1=A1+B1,问sum1=X的概率是多少?

    例如:sum1=A1+B1=5的概率是多少?

    • 解法:P(sum1=5)=[P(A1=1)P(B1=4)]+[P(A1=2)P(B1=3)]+[P(A1=3)P(B1=2)]+[P(A1=4)P(B1=1)]=[(1/61/6)+(1/61/6)+(1/61/6)+(1/61/6)]P(sum1=5) \\ =[P(A1=1)*P(B1=4)] + [P(A1=2)*P(B1=3)] + [P(A1=3)*P(B1=2)]+[P(A1=4)*P(B1=1)] \\ =[(1/6 * 1/6)+(1/6 * 1/6)+(1/6 * 1/6)+(1/6 * 1/6)]
  • 问题2:知乎进食问题 , 人吃饭,y1y1函数表示一口一口吃,每口质量能不一样(多一点或少一点),

    y2y2表示这一口吃下去会被消化,经过tt时间后还剩yty^t克, 现在问:你不断不断的吃,到了t时刻,肚子里有多少食物待消化?

  • 当t=9时,F(9)=09f1(t)f2(100t)dtF(9)=\int_{0}^{9}f_1(t)f_2(100-t)dt

  • 问题3:pid控制算法, (比例-积分-微分控制器)

posted @   马角的逆袭  阅读(262)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示