OpenCV GaborFilter - eiichiromomma/CVMLAB GitHub Wiki
(OpenCV) Gabor Filter
Gabor Filterで遊んでみた
原画像
カーネル(20倍表示)
操作画面
二乗した画像
動作が怪しいので作り直し。
このバージョンからカーネルの取得が標準で出来るようになった。
getGaborKernel(...)
getGaborKernel(ksize, sigma, theta, lambd, gamma[, psi[, ktype]]) -> retval
が定義されていて
kern = cv2.getGaborKernel((21,21), 5,np.pi/2, 50, 5/21., ktype=cv2.CV_32F)
のような感じで
plt.imshow(kern)
とすると
のようになる。あとはfilter2Dで使えば良い。 ksizeがカーネルサイズのtupleな点と角度はラジアン表記な点に注意。
作成されるカーネルは値が小さいのでsamples/python2/gabor_threads.pyでも
kern = cv2.getGaborKernel((ksize, ksize), 4.0, theta, 10.0, 0.5, 0, ktype=cv2.CV_32F)
kern /= 1.5*kern.sum()
のようにしている。(下のサンプルではやってない)
# encoding: utf-8
# gabor.py
# 2012-3-8
# 2013-8-30 getGaborKernel
# 2016-6-19 fixed bugs
# Eiichiro Momma
__author__ = 'momma'
import numpy as np
import cv2 as cv
kernel_size =21
pos_sigma = 5
pos_lm = kernel_size-2
pos_th = 0
pos_gam = 100
pos_psi = 90
def Process():
sig = pos_sigma
lm = pos_lm+2
th = pos_th*np.pi/180.
gm = pos_gam/100.
ps = (pos_psi-180)*np.pi/180
print ('kern_size=' + str(kernel_size) + ', sig=' + str(sig) + ', th=' + str(th) + ', lm=' + str(lm) +', gm=' + str(gm) + ', ps=' + str(ps))
kernel = cv.getGaborKernel((kernel_size,kernel_size),sig,th,lm,gm,ps)
kernelimg = kernel/2.+0.5
global src_f
dest = cv.filter2D(src_f, cv.CV_32F,kernel)
cv.imshow('Process window', dest)
cv.imshow('Kernel', cv.resize(kernelimg, (kernel_size*20,kernel_size*20)))
cv.imshow('Mag', np.power(dest,2))
def cb_sigma(pos):
global pos_sigma
if pos > 0:
pos_sigma = pos
else:
pos_sigma = 1
Process()
def cb_lm(pos):
global pos_lm
pos_lm = pos
Process()
def cb_th(pos):
global pos_th
pos_th = pos
Process()
def cb_psi(pos):
global pos_psi
pos_psi = pos
Process()
def cb_gam(pos):
global pos_gam
pos_gam = pos
Process()
if __name__ == '__main__':
image = cv.imread('cat.jpg',1)
cv.imshow('Src',image)
src = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
global src_f
src_f = np.array(src, dtype=np.float32)
src_f /= 255.
if not kernel_size%2:
kernel_size += 1
cv.namedWindow('Process window',1)
cv.createTrackbar('Sigma','Process window',pos_sigma,kernel_size//2,cb_sigma)
cv.createTrackbar('Lambda', 'Process window', pos_lm, kernel_size-2, cb_lm)
cv.createTrackbar('Theta', 'Process window', pos_th, 360, cb_th)
cv.createTrackbar('gamma', 'Process window', pos_psi, 300, cb_gam)
cv.createTrackbar('Psi', 'Process window', pos_psi, 360, cb_psi)
Process()
cv.waitKey(0)
cv.destroyAllWindows()
Pythonでも使いたかったので、今回は使わず。
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <math.h>
cv::Mat mkKernel(int ks, double sig, double th, double lm, double ps)
{
int hks = (ks-1)/2;
double theta = th*CV_PI/180;
double psi = ps*CV_PI/180;
double del = 2.0/(ks-1);
double lmbd = lm;
double sigma = sig/ks;
double x_theta;
double y_theta;
cv::Mat kernel(ks,ks, CV_32F);
for (int y=-hks; y<=hks; y++)
{
for (int x=-hks; x<=hks; x++)
{
x_theta = x*del*cos(theta)+y*del*sin(theta);
y_theta = -x*del*sin(theta)+y*del*cos(theta);
kernel.at<float>(hks+y,hks+x) = (float)exp(-0.5*(pow(x_theta,2)+pow(y_theta,2))/pow(sigma,2))* cos(2*CV_PI*x_theta/lmbd + psi);
}
}
return kernel;
}
int kernel_size=21;
int pos_sigma= 5;
int pos_lm = 50;
int pos_th = 0;
int pos_psi = 90;
cv::Mat src_f;
cv::Mat dest;
void Process(int , void *)
{
double sig = pos_sigma;
double lm = 0.5+pos_lm/100.0;
double th = pos_th;
double ps = pos_psi;
cv::Mat kernel = mkKernel(kernel_size, sig, th, lm, ps);
cv::filter2D(src_f, dest, CV_32F, kernel);
cv::imshow("Process window", dest);
cv::Mat Lkernel(kernel_size*20, kernel_size*20, CV_32F);
cv::resize(kernel, Lkernel, Lkernel.size());
Lkernel /= 2.;
Lkernel += 0.5;
cv::imshow("Kernel", Lkernel);
cv::Mat mag;
cv::pow(dest, 2.0, mag);
cv::imshow("Mag", mag);
}
int main(int argc, char** argv)
{
cv::Mat image = cv::imread("cat.jpg)",1);
cv::imshow("Src", image);
cv::Mat src;
cv::cvtColor(image, src, CV_BGR2GRAY);
src.convertTo(src_f, CV_32F, 1.0/255, 0);
if (!kernel_size%2)
{
kernel_size+=1;
}
cv::namedWindow("Process window", 1);
cv::createTrackbar("Sigma", "Process window", &pos_sigma, kernel_size, Process);
cv::createTrackbar("Lambda", "Process window", &pos_lm, 100, Process);
cv::createTrackbar("Theta", "Process window", &pos_th, 180, Process);
cv::createTrackbar("Psi", "Process window", &pos_psi, 360, Process);
Process(0,0);
cv::waitKey(0);
return 0;
}
# encoding: utf-8
# gabor.py
# 2012-3-8
# Eiichiro Momma
__author__ = 'momma'
import numpy as np
import cv2 as cv
def mkKernel(ks, sig, th , lm, ps):
if not ks%2:
exit(1)
hks = ks/2
theta = th * np.pi/180.
psi = ps * np.pi/180.
xs=np.linspace(-1.,1.,ks)
ys=np.linspace(-1.,1.,ks)
lmbd = np.float(lm)
x,y = np.meshgrid(xs,ys)
sigma = np.float(sig)/ks
x_theta = x*np.cos(theta)+y*np.sin(theta)
y_theta = -x*np.sin(theta)+y*np.cos(theta)
return np.array(np.exp(-0.5*(x_theta**2+y_theta**2)/sigma**2)*np.cos(2.*np.pi*x_theta/lmbd + psi),dtype=np.float32)
src_f = 0
kernel_size =21
pos_sigma = 5
pos_lm = 50
pos_th = 0
pos_psi = 90
def Process():
sig = pos_sigma
lm = 0.5+pos_lm/100.
th = pos_th
ps = pos_psi
kernel = mkKernel(kernel_size, sig, th, lm, ps )
kernelimg = kernel/2.+0.5
global src_f
dest = cv.filter2D(src_f, cv.CV_32F,kernel)
cv.imshow('Process window', dest)
cv.imshow('Kernel', cv.resize(kernelimg, (kernel_size*20,kernel_size*20)))
cv.imshow('Mag', np.power(dest,2))
def cb_sigma(pos):
global pos_sigma
if pos > 0:
pos_sigma = pos
else:
pos_sigma = 1
Process()
def cb_lm(pos):
global pos_lm
pos_lm = pos
Process()
def cb_th(pos):
global pos_th
pos_th = pos
Process()
def cb_psi(pos):
global pos_psi
pos_psi = pos
Process()
if __name__ == '__main__':
image = cv.imread("cat.jpg)",1);
cv.imshow('Src',image)
src = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
#global src_f
src_f = np.array(src, dtype=np.float32)
src_f /= 255.
if not kernel_size%2:
kernel_size += 1
cv.namedWindow('Process window',1)
cv.createTrackbar('Sigma','Process window',pos_sigma,kernel_size,cb_sigma)
cv.createTrackbar('Lambda', 'Process window', pos_lm, 100, cb_lm)
cv.createTrackbar('Phase', 'Process window', pos_th, 180, cb_th)
cv.createTrackbar('Psi', 'Process window', pos_psi, 360, cb_psi)
Process()
cv.waitKey(0)
cv.destroyAllWindows()