opencv图像处理常用操作

图像的平滑处理

平滑,也称 模糊, 平滑处理时需要用到一个滤波器 。滤波器想象成一个包含加权系数的窗口,这个加权系数也叫做核或者模版。

<code class="language-cpp hljs  has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 图像平滑处理分而学之.cpp : 定义控制台应用程序的入口点。</span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//</span>
    <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include "stdafx.h"</span>
    <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <iostream></span>
    <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <opencv2/opencv.hpp></span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">using</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">namespace</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">std</span>;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">using</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">namespace</span> cv;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">const</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> MAX_KERNEL_LENGTH = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">31</span>;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> _tmain(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> argc, _TCHAR* argv[])
    {
        Mat img = imread(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"D:\\lenargb.jpg"</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>);
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (img.empty())
        {
            <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">cout</span> << <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"无法读入图像"</span> << endl;
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;
        }
        Mat dest;

    <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#pragma region 归一化平滑</span>
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>; i < MAX_KERNEL_LENGTH; i++)
        {
            blur(img, dest, Size(i, i), Point(-<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>, -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>));<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//size(i,i)内核大小,最小为(1,1);</span>
            imshow(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"归一化平滑图像"</span>, dest);
            waitKey(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">100</span>);

        }
    <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#pragma endregion</span>
    <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#pragma region 高斯平滑</span>
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>; i < MAX_KERNEL_LENGTH; i = i + <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>)
        {
            GaussianBlur(img, dest, Size(i, i), <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//size的两个参数必须都为正奇数,第四个参数是x方向的标准差,第五个参数是y方向的标准差,如果是0,表示从内核大小计算得到;</span>
            imshow(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"高斯平滑图像图像"</span>, dest);
            waitKey(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">100</span>);
        }
    <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#pragma endregion</span>

    <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#pragma region 中值平滑</span>
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>; i < MAX_KERNEL_LENGTH; i = i + <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>)
        {
            medianBlur(img, dest, i);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//第三个参数为核的边长,必须为奇数,一般中值平滑用的都是正方形所以只用一个参数就好;</span>
            imshow(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"中值平滑"</span>, dest);
            waitKey(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">100</span>);
        }
    <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#pragma endregion</span>

        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//waitKey(0);</span>
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;
    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li></ul>

图像阈值操作

为了从一副图像中提取出我们需要的部分,应该用图像中的每一个像素点的灰度值与选取的阈值进行比较,并作出相应的判断。 
一旦找到了需要分割的物体的像素点,我们可以对这些像素点设定一些特定的值来表示。(例如:可以将该物体的像素点的灰度值设定为:‘0’(黑色),其他的像素点的灰度值为:‘255’(白色); 
OpenCV中提供了阈值(threshold)函数 有五种类型 
1. 二进制阈值化 
先要选定一个特定的阈值量,比如:120,这样,新的阈值产生规则可以解释为大于120的像素点的灰度值设定为最大值(如8位灰度值最大为255),灰度值小于120的像素点的灰度值设定为0。 
2. 反二进制阈值化 
该阈值化与二进制阈值化相似,先选定一个特定的灰度值作为阈值,不过最后的设定值相反。 
3. 截断阈值化 
同样首先需要选定一个阈值,图像中大于该阈值的像素点被设定为该阈值,小于该阈值的保持不变 
4. 阈值化为0 
首先需要选定一个阈值,像素点的灰度值大于该阈值的不进行任何改变;2 像素点的灰度值小于该阈值的,其灰度值全部变为0 
5. 反阈值化为0 
原理类似于0阈值,但是在对图像做处理的时候相反,即:像素点的灰度值小于该阈值的不进行任何改变,而大于该阈值的部分,其灰度值全部变为0。 
filter2D函数能够对图像按照模版进行滤波

<code class="language-cpp hljs  has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 基本阈值操作2.cpp : 定义控制台应用程序的入口点。</span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//</span>

    <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include "stdafx.h"</span>
    <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <iostream></span>
    <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <opencv2/opencv.hpp></span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">using</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">namespace</span>  <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">std</span>;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">using</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">namespace</span> cv;


    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> respond(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>*);
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">const</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> * window_name = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"图片"</span>;
    Mat src_gray;
    Mat dst;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> threshhold_type = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">const</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> max_type = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> threshhold_value = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> max_value = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">255</span>;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> _tmain(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> argc, _TCHAR* argv[])
    {
        namedWindow(window_name, WINDOW_AUTOSIZE);
        Mat src = imread(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"E:\\code\\test\\image\\tiantan.png"</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>);
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (src.empty())
        {
            <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">cout</span> << <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"无法正常载入图片"</span> << endl; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;
        }
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//转换为灰度图;</span>
        cvtColor(src, src_gray, CV_RGB2GRAY);
        imshow(window_name, src_gray);
        createTrackbar(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"阈值类型"</span>, window_name, &threshhold_type, max_type, respond);
        createTrackbar(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"阈值大小"</span>, window_name, &threshhold_value, max_value, respond);
        waitKey(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>);
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;
    }
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> respond(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>*)
    {
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 0:二进制阈值
        1: 反二进制阈值
        2: 截断阈值
        3: 0阈值
        4: 反0阈值
        5:原灰度图;
        */</span>
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (threshhold_type==<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>)
        {
            imshow(window_name, src_gray);
        }
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span>
        {
            threshold(src_gray, dst, threshhold_value, max_value, threshhold_type);
            imshow(window_name, dst);
        }
    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li></ul>

实现自己的线性滤波器

OpenCV为我们提供了函数 filter2D ,来实现核卷积;

<code class="language-cpp hljs  has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 实现自己的滤波器2.cpp : 定义控制台应用程序的入口点。</span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//</span>

    <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include "stdafx.h"</span>
    <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <iostream></span>
    <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <opencv2/opencv.hpp></span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">using</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">namespace</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">std</span>;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">using</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">namespace</span> cv;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> respond(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>*);
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">const</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> * window_name = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"实现自己的滤波器"</span>;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> value = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;
    Mat src,dst,kernel;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">const</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> max_value = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">100</span>;

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> _tmain(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> argc, _TCHAR* argv[])
    {
        src = imread(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"E:\\code\\test\\image\\lena.png"</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>);
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (src.data==NULL)
        {
            <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">cout</span> << <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"无法加载图片"</span> << endl;
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;
        }
        namedWindow(window_name, WINDOW_AUTOSIZE);
        imshow(window_name, src);
        createTrackbar(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"核的大小"</span>, window_name, &value, max_value, respond);
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>)
        {

            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> c = waitKey(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>);
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (c==<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">27</span>)
            {
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;
            }
        }

        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;
    }

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> respond(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>*)
    {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> kernel_size = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span> + value * <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>;
        kernel = Mat::ones(kernel_size, kernel_size, CV_32F)/(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span>)(kernel_size*kernel_size);
        filter2D(src, dst, -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>, kernel, Point(-<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>, -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>));
        imshow(window_name, dst);
    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li></ul>

Sobel导数

Sobel 算子是一个离散微分算子 (discrete differentiation operator)。 它用来计算图像灰度函数的近似梯度。Sobel 算子结合了高斯平滑和微分求导。

<code class="language-cpp hljs  has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Sobel导数.cpp : 定义控制台应用程序的入口点。</span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//</span>
    <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include "stdafx.h"</span>

    <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include "opencv2/imgproc/imgproc.hpp"</span>
    <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include "opencv2/highgui/highgui.hpp"</span>
    <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <stdlib.h></span>
    <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <stdio.h></span>

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">using</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">namespace</span> cv;

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/** @function main */</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> main(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> argc, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span>** argv)
    {

        Mat src, src_gray;
        Mat grad;
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span>* window_name = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Sobel Demo - Simple Edge Detector"</span>;
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> scale = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> delta = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> ddepth = CV_16S;

        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//int c;</span>

        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/// 装载图像</span>
        src = imread(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"E://code//test//image//lena.png"</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>);

        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (!src.data)
        {
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;
        }

        GaussianBlur(src, src, Size(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>), <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, BORDER_DEFAULT);
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/// 创建显示窗口</span>
        namedWindow(window_name, CV_WINDOW_AUTOSIZE);
        imshow(window_name, src);
        waitKey(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3000</span>);
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/// 转换为灰度图</span>
        cvtColor(src, src_gray, CV_RGB2GRAY);


        imshow(window_name, src_gray);
        waitKey(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3000</span>);
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/// 创建 grad_x 和 grad_y 矩阵</span>
        Mat grad_x, grad_y;
        Mat abs_grad_x, abs_grad_y;

        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/// 求 X方向梯度</span>

        Scharr( src_gray, grad_x, ddepth, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, scale, delta, BORDER_DEFAULT );
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//Sobel(src_gray, grad_x, ddepth, 1, 0, 3, scale, delta, BORDER_DEFAULT);</span>
        convertScaleAbs(grad_x, abs_grad_x);

        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/// 求Y方向梯度</span>
        Scharr( src_gray, grad_y, ddepth, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>, scale, delta, BORDER_DEFAULT );
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//Sobel(src_gray, grad_y, ddepth, 0, 1, 3, scale, delta, BORDER_DEFAULT);</span>
        convertScaleAbs(grad_y, abs_grad_y);

        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/// 合并梯度(近似)</span>

        addWeighted(abs_grad_x, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0.5</span>, abs_grad_y, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0.5</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, grad);

        imshow(window_name, grad);

        waitKey(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>);

        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;
    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li></ul>
//其实不简单也没有关系,因为只是相对大小,在图像的对比中,依然能够找到边界;

Laplace 算子

一阶导数的极值位置,二阶导数为0。所以我们也可以用这个特点来作为检测图像边缘的方法。 但是, 二阶导数的0值不仅仅出现在边缘(它们也可能出现在无意义的位置),但是我们可以过滤掉这些点。 
实际上,由于 Laplacian使用了图像梯度,它内部调用了 Sobel 算子。

<code class="language-cpp hljs  has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Laplace算子.cpp : 定义控制台应用程序的入口点。</span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//</span>

    <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include "stdafx.h"</span>

    <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include "opencv2/imgproc/imgproc.hpp"</span>
    <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include "opencv2/highgui/highgui.hpp"</span>
    <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <stdlib.h></span>
    <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <stdio.h></span>

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">using</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">namespace</span> cv;

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/** @函数 main */</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> main(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> argc, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span>** argv)
    {
        Mat src, src_gray, dst;
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> kernel_size = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>;
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> scale = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> delta = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> ddepth = CV_16S;
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span>* window_name = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Laplace Demo"</span>;

        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> c;

        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/// 装载图像</span>
        src = imread(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"E://code//test//image//lena.png"</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>);

        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (!src.data)
        {
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;
        }

        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/// 使用高斯滤波消除噪声</span>
        GaussianBlur(src, src, Size(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>), <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, BORDER_DEFAULT);

        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/// 转换为灰度图</span>
        cvtColor(src, src_gray, CV_RGB2GRAY);

        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/// 创建显示窗口</span>
        namedWindow(window_name, CV_WINDOW_AUTOSIZE);
        imshow(window_name, src);
        waitKey(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2000</span>);
        imshow(window_name, src_gray);
        waitKey(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3000</span>);

        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/// 使用Laplace函数</span>
        Mat abs_dst;

        Laplacian(src_gray, dst, ddepth, kernel_size, scale, delta, BORDER_DEFAULT);
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//ddepth: 输出图像的深度。 因为输入图像的深度是 CV_8U ,这里我们必须定义 ddepth = CV_16S 以避免外溢。</span>
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//下面大概求绝对值;</span>
        convertScaleAbs(dst, abs_dst);

        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/// 显示结果</span>
        imshow(window_name, abs_dst);

        waitKey(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>);

        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;
    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li></ul>

Canny 边缘检测

步骤 
1. 消除噪声。 使用高斯平滑滤波器卷积降噪。 
2. 计算梯度幅值和方向。 此处,使用Sobel滤波器 
3. 非极大值 抑制。 这一步排除非边缘像素, 仅仅保留了一些细线条(候选边缘)。 
4. 滞后阈值: 最后一步,Canny 使用了滞后阈值,滞后阈值需要两个阈值(高阈值和低阈值): Canny 推荐的 高:低 阈值比在 2:1 到3:1之间。

<code class="language-cpp hljs  has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Canny边缘检测.cpp : 定义控制台应用程序的入口点。</span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//</span>

    <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include "stdafx.h" </span>
    <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include "opencv2/imgproc/imgproc.hpp"</span>
    <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include "opencv2/highgui/highgui.hpp"</span>
    <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <stdlib.h></span>
    <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <stdio.h></span>

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">using</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">namespace</span> cv;

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/// 全局变量</span>

    Mat src, src_gray;
    Mat dst, detected_edges;

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//int edgeThresh = 1;</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> lowThreshold=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">const</span> max_lowThreshold = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">100</span>;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> ratio = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> kernel_size = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span>* window_name = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Edge Map"</span>;

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
    * @函数 CannyThreshold
    * @简介: trackbar 交互回调 - Canny阈值输入比例1:3
    */</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> CannyThreshold(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>*)
    {
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/// 使用 3x3内核降噪</span>
        blur(src_gray, detected_edges, Size(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>));

        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/// 运行Canny算子</span>
        Canny(detected_edges, detected_edges, lowThreshold, lowThreshold*ratio, kernel_size);
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//第一个参数是原图像,第二个参数是输出图像,支持本地计算,第三个参数是低阈值,第四个参数是高阈值,第五个参数是内部sobel算子使用的内核大小。</span>
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/// 使用 Canny算子输出边缘作为掩码显示原图像</span>
        dst = Scalar::all(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>);
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//把dst填充为黑色</span>
        src.copyTo(dst, detected_edges);
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//第一个参数为输出图像,第二个参数为掩码;即把第二个图像中非0的部分在src中的像素复制给dst;</span>

        imshow(window_name, dst);
    }


    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/** @函数 main */</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> main(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> argc, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span>** argv)
    {
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/// 装载图像</span>
        src = imread(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"E:\\code\\test\\image\\lena.png"</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>);

        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (!src.data)
        {
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;
        }

        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/// 创建与src同类型和大小的矩阵(dst)</span>
        dst.create(src.size(), src.type());

        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/// 原图像转换为灰度图像</span>
        cvtColor(src, src_gray, CV_BGR2GRAY);

        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/// 创建显示窗口</span>
        namedWindow(window_name, CV_WINDOW_AUTOSIZE);

        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/// 创建trackbar</span>
        createTrackbar(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Min Threshold:"</span>, window_name, &lowThreshold, max_lowThreshold, CannyThreshold);

        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/// 显示图像</span>
        CannyThreshold(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>);

        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/// 等待用户反应</span>
        waitKey(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>);

        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;
    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li><li style="box-sizing: border-box; padding: 0px 5px;">70</li><li style="box-sizing: border-box; padding: 0px 5px;">71</li><li style="box-sizing: border-box; padding: 0px 5px;">72</li><li style="box-sizing: border-box; padding: 0px 5px;">73</li><li style="box-sizing: border-box; padding: 0px 5px;">74</li><li style="box-sizing: border-box; padding: 0px 5px;">75</li><li style="box-sizing: border-box; padding: 0px 5px;">76</li></ul>

canny检测结果

<code class="language-cpp hljs  has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/// 使用 3x3内核降噪</span>
    blur(src_gray, detected_edges, Size(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>));

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/// 运行Canny算子</span>
    Canny(detected_edges, detected_edges, lowThreshold, lowThreshold*ratio, kernel_size);
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//第一个参数是原图像,第二个参数是输出图像,支持本地计算,第三个参数是低阈值,第四个参数是高阈值,第五个参数是内部sobel算子使用的内核大小。</span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/// 使用 Canny算子输出边缘作为掩码显示原图像</span></code>

猜你喜欢

转载自blog.csdn.net/merryken/article/details/45933111