一:源码
https://github.com/Itseez/opencv/blob/master/samples/python2/coherence.py
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
二:
opencv mat.reshape c是行优先, matlab 列优先
三:
http://www.rosoo.net/a/201004/9157.html#CornerEigenValsAndVecs
#!/usr/bin/env python
'''
Texture flow direction estimation.
Sample shows how cv2.cornerEigenValsAndVecs function can be used
to estimate image texture flow direction.
Usage:
texture_flow.py []
'''
import numpy as np
import cv2
if __name__ == '__main__':
import sys
try:
fn = sys.argv[1]
except:
fn = 'data/starry_night.jpg'
img = cv2.imread(fn)
if img is None:
print 'Failed to load image file:', fn
sys.exit(1)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
h, w = img.shape[:2]
eigen = cv2.cornerEigenValsAndVecs(gray, 15, 3)
eigen = eigen.reshape(h, w, 3, 2) # [[e1, e2], v1, v2]
flow = eigen[:,:,2]
vis = img.copy()
vis[:] = (192 + np.uint32(vis)) / 2
d = 12
points = np.dstack( np.mgrid[d/2:w:d, d/2:h:d] ).reshape(-1, 2)
for x, y in points:
vx, vy = np.int32(flow[y, x]*d)
cv2.line(vis, (x-vx, y-vy), (x+vx, y+vy), (0, 0, 0), 1, cv2.LINE_AA)
cv2.imshow('input', img)
cv2.imshow('flow', vis)
cv2.waitKey()
int main (int argc, char** argv)
{
cv::TickMeter tm;
tm.start();
cv::Mat img = cv::imread(argv[1]);
cv::Mat gray = cv::Mat();
cv::cvtColor(img, gray, CV_BGR2GRAY);
// to preserve the original image
cv::Mat flow = gray.clone();
int width = img.cols;
int height = img.rows;
int graySize = width * height;
// "brighten" the flow image
// C++ version of:
// vis[:] = (192 + np.uint32(vis)) / 2
for (unsigned int i=0; i channels;
cv::split(eigen, channels);
int d = 12;
cv::Scalar col(0, 0, 0);
// C++ version of:
// points = np.dstack( np.mgrid[d/2:w:d, d/2:h:d] ).reshape(-1, 2)
// including the actual line drawing part
for (unsigned int y=(d/2); y(p) * (d/2);
float dy = channels[5].at(p) * (d/2);
cv::Point p0(p.x - dx, p.y - dy);
cv::Point p1(p.x + dx, p.y + dy);
cv::line(flow, p0, p1, col, 1);
}
}
}
tm.stop();
std::cout<<"Flow image generated in "<