关闭

Coherence-Enhancing Shock Filters(附源码)

标签: 滤镜OpenCVCoherenceNPAR
2962人阅读 评论(6) 收藏 举报
分类:

引言

这篇博客是基于对Joachim Weickert的文章《Coherence-Enhancing Shock Filters》的实现。但是我并没有阅读原文,参考了OpenCV的python源码改写而成。嗯,我真是一个勤劳的代码翻译工。
python源码可以在OpenCV 300里面的目录

XXX(OpenCV的安装目录)\sources\samples\python2\coherence.py

先来看一下效果,

这里写图片描述

代码

Python代码

Coherence-enhancing filtering example
=====================================
inspired by
  Joachim Weickert "Coherence-Enhancing Shock Filters"
  http://www.mia.uni-saarland.de/Publications/weickert-dagm03.pdf

import numpy as np
import cv2

def coherence_filter(img, sigma = 11, str_sigma = 11, blend = 0.5, iter_n = 4):
    h, w = img.shape[:2]

    for i in xrange(iter_n):
        print i,

        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        eigen = cv2.cornerEigenValsAndVecs(gray, str_sigma, 3)
        eigen = eigen.reshape(h, w, 3, 2)  # [[e1, e2], v1, v2]
        x, y = eigen[:,:,1,0], eigen[:,:,1,1]

        gxx = cv2.Sobel(gray, cv2.CV_32F, 2, 0, ksize=sigma)
        gxy = cv2.Sobel(gray, cv2.CV_32F, 1, 1, ksize=sigma)
        gyy = cv2.Sobel(gray, cv2.CV_32F, 0, 2, ksize=sigma)
        gvv = x*x*gxx + 2*x*y*gxy + y*y*gyy
        m = gvv < 0

        ero = cv2.erode(img, None)
        dil = cv2.dilate(img, None)
        img1 = ero
        img1[m] = dil[m]
        img = np.uint8(img*(1.0 - blend) + img1*blend)
    print 'done'
    return img


if __name__ == '__main__':
    import sys
    try:
        fn = sys.argv[1]
    except:
        fn = '../data/lena.jpg'

    src = cv2.imread(fn)

    def nothing(*argv):
        pass

    def update():
        sigma = cv2.getTrackbarPos('sigma', 'control')*2+1
        str_sigma = cv2.getTrackbarPos('str_sigma', 'control')*2+1
        blend = cv2.getTrackbarPos('blend', 'control') / 10.0
        print 'sigma: %d  str_sigma: %d  blend_coef: %f' % (sigma, str_sigma, blend)
        dst = coherence_filter(src, sigma=sigma, str_sigma = str_sigma, blend = blend)
        cv2.imshow('dst', dst)

    cv2.namedWindow('control', 0)
    cv2.createTrackbar('sigma', 'control', 9, 15, nothing)
    cv2.createTrackbar('blend', 'control', 7, 10, nothing)
    cv2.createTrackbar('str_sigma', 'control', 9, 15, nothing)


    print 'Press SPACE to update the image\n'

    cv2.imshow('src', src)
    update()
    while True:
        ch = 0xFF & cv2.waitKey()
        if ch == ord(' '):
            update()
        if ch == 27:
            break
    cv2.destroyAllWindows()

C++代码

/* ==============================================
*   Coherence-Enhancing Shock Filters
*  Author:WinCoder@qq.com
*  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);

        Mat x,y;
        x = vec[2];
        y = vec[3];

        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++)
            {
                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);
                }
            }
        }
        I = I*(1.0-blend)+img1*blend;
    }
    return I;
}

效果

整体效果看起来有一种艺术动漫效果风格。调节各种参数,自行体会。

这里写图片描述这里写图片描述

可执行程序下载

新浪网盘点此下载
CSDN资源下载

参考文献

Coherence-Enhancing Shock Filters,Joachim Weickert
OpenCV官方文档

转载请保留以下信息

作者 日期 联系方式
风吹夏天 2015年11月19日 wincoder@qq.com
3
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:155878次
    • 积分:2188
    • 等级:
    • 排名:第18125名
    • 原创:50篇
    • 转载:9篇
    • 译文:0篇
    • 评论:99条
    最新评论