From:http://blog.csdn.net/bluecol/article/details/49924739
引言
这篇博客是基于对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 |