圖像的卷積(濾波)運算(一)——圖像梯度

1. 卷積/濾波原理

首先要明確的一點是圖像的卷積/濾波運算,是針對原圖像每個像素進行處理,獲得一個新的圖像的過程。那麼進行怎麼樣的運算呢?要知道圖像可以被人所識別,是由於圖像中每一個像素並不徹底是離散而獨立的,每一個像素都跟周圍的像素相關。所以,對每個像素,選定其周圍必定範圍內的像素值進行運算,獲得新的圖像的像素值也必定是相關的。而這個範圍,就是卷積/濾波的窗口。算法

只有相關的像素值是不夠的,還須要改變因子——也就是咱們說的卷積核了。它就是以前說的卷積/濾波的窗口大小,一般由數學原理推導出來的。函數

最後,將窗口內覆蓋的像素值和卷積核值相乘並相加,就獲得新的像素值填充到新的圖像中。對每一個像素值都這樣作,就是卷積/濾波運算後新的圖像了。spa

2. 具體實例

以X方向上的一維卷積/濾波爲例,選取一個卷積核(-1,0,1),對於圖像像素X,其卷積運算的結果Y=-1 × Xa + 0 × X + 1 × Xb,即老是X的後一個像素與前一個像素之差。示意圖以下:.

其具體實現代碼:.net

#include <iostream>
#include <opencv2\opencv.hpp>

using namespace cv;
using namespace std;

int main()
{
    //從文件中讀取成灰度圖像
    const char* imagename = "D:\\Data\\imgDemo\\lena.jpg";
    Mat img = imread(imagename, IMREAD_GRAYSCALE);
    if (img.empty())
    {
        fprintf(stderr, "Can not load image %s\n", imagename);
        return -1;
    }

    //OpenCV函數進行一維卷積(梯度圖)
    Mat xKernel = (Mat_<double>(1, 3) << -1, 0, 1);         //卷積算子
    Mat Ix;
    filter2D(img, Ix, -1, xKernel);

    //自建算法進行一維卷積(梯度圖)
    Mat Ixx;
    Ixx.create(img.cols, img.rows, CV_8UC1);
    double xk[3] = { -1, 0, 1 };            //卷積算子
    for (int i = 0; i < img.rows; ++i)
    {
        for (int j = 0; j < img.cols; ++j)
        {
            //img.at<uchar>(i, j) = 255;
            uchar b[3] = { 0 };
            b[0] = (j == 0 ? 0 : img.at<uchar>(i, j - 1));
            b[1] = img.at<uchar>(i, j);
            b[2] = (j == img.cols - 1 ? 0 : img.at<uchar>(i, j + 1));

            double value = xk[0] * b[0] + xk[1] * b[1] + xk[2] * b[2];
            value = (std::min)(std::max(value, 0.0), 255.0);
            Ixx.at<uchar>(i, j) = (uchar)value;
        }
    }

    //比較二者的結果
    Mat c;
    compare(Ix, Ixx, c, CMP_EQ);

    //顯示圖像
    imshow("原始", img);
    imshow("梯度圖(CV)", Ix);
    imshow("梯度圖(MY)", Ixx);
    imshow("比較結果", c);

    waitKey();
    return 0;
}

在這裏分別經過OpenCV的filter2D和本身的算法實現了X方向上的一維卷積/濾波運算,顯示了其結果圖。最後還用compare函數比較二者的差別,純白(像素值255)色表示二者無差別。其運行結果以下:
code

3. 圖像梯度圖

這裏的卷積核(-1,0,1)實際上是從圖像的梯度推導出來的。若是把圖像看做是函數f(x),那麼其X方向上梯度也就是函數X方向上的變化率爲:

對全部的像素卷積運算都會除以2,對結果可有可無,所以能夠將其捨棄。最後就獲得卷積核(-1,0,1)。
除此以外,也能夠在Y方向上進行卷積,獲得Y方向上的卷積圖,只不過卷積核須要轉置。blog

4. 參考資料

1.圖像梯度的基本原理
2.圖像梯度計算get

相關文章
相關標籤/搜索