天天看點

Coherence-Enhancing Shock Filters 代碼及詳細注釋【OpenCV】

本文代碼參考自 部落格 原作者論文 下載下傳位址

// CoherenceFilter.cpp : 定義控制台應用程式的入口點。
//
 
#include "stdafx.h"
#include <opencv2/opencv.hpp>
 
using namespace cv;
 
/* ==============================================
*   Coherence-Enhancing Shock Filters
*  Author:[email protected]
*  inspired by
*  Joachim Weickert "Coherence-Enhancing Shock Filters"
*  http://www.mia.uni-saarland.de/Publications/weickert-dagm03.pdf
*
*   Paras:
*   @img        : input image ranging value from 0 to 255.
*   @sigma      : sobel kernel size.
*   @str_sigma  : neighborhood size,see detail in reference[2]
*   @belnd      : blending coefficient.default value 0.5.
*   @iter       : number of iteration.
*
*   Example:
*   Mat dst = CoherenceFilter(I,11,11,0.5,4);
*   imshow("shock filter",dst);
*/
 
Mat CoherenceFilter(Mat img, int sigma, int str_sigma, float blend, int iter)
{
    Mat I = img.clone();
    int height = I.rows;
    int width = I.cols;
 
    for (int i = 0; i <iter; i++)
    {
        Mat gray;
        cvtColor(I, gray, COLOR_BGR2GRAY);
        // 計算特征值和特征向量
        Mat eigen;
        cornerEigenValsAndVecs(gray, eigen, str_sigma, 3);
 
        vector<Mat> vec;
        split(eigen, vec);// vec[0]: λ1, vec[1]: λ2, vec[2]: x1, vec[3]: y1, vec[4]: x2,  vec[5]: y2
 
        // 主特征向量 w
        Mat x, y;
        x = vec[2]; // c
        y = vec[3]; // s
 
        // Sobel近似求解二階導數
        Mat gxx, gxy, gyy;
        Sobel(gray, gxx, CV_32F, 2, 0, sigma);
        Sobel(gray, gxy, CV_32F, 1, 1, sigma);
        Sobel(gray, gyy, CV_32F, 0, 2, sigma);
 
        Mat ero;
        Mat dil;
        erode(I, ero, Mat());   // 最小值附近進行腐蝕
        dilate(I, dil, Mat());  // 最大值附近進行膨脹
 
        Mat img1 = ero;
        for (int nY = 0; nY<height; nY++)
        {
            for (int nX = 0; nX<width; nX++)
            {
                // 邊界檢測子v(ww)
                if (x.at<float>(nY, nX)* x.at<float>(nY, nX)* gxx.at<float>(nY, nX)
                    + 2 * x.at<float>(nY, nX)* y.at<float>(nY, nX)* gxy.at<float>(nY, nX)
                    + y.at<float>(nY, nX)* y.at<float>(nY, nX)* gyy.at<float>(nY, nX)<0)
                {
                    img1.at<Vec3b>(nY, nX) = dil.at<Vec3b>(nY, nX); // 最大值的影響區域 dil
                }
                // 否則是最小值的影響區域 ero
            }
        }
        // 和原圖按比例混合
        I = I*(1.0 - blend) + img1*blend;
    }
    return I;
}
 
int main()
{
    Mat img = imread("D:/Pictures/beard.jpg", 1);
    Mat result = CoherenceFilter(img, 11, 11, 0.5, 2);
    imshow("Result", result);
    waitKey(0);
 
    return 0;
}      
Coherence-Enhancing Shock Filters 代碼及詳細注釋【OpenCV】

繼續閱讀