-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfourierDescriptor.py
71 lines (59 loc) · 3.25 KB
/
fourierDescriptor.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import cv2
import numpy as np
MIN_DESCRIPTOR = 32 # surprisingly enough, 2 descriptors are already enough
##计算傅里叶描述子
def fourierDesciptor(res):
# Laplacian算子进行八邻域检测
gray = cv2.cvtColor(res, cv2.COLOR_BGR2GRAY)
dst = cv2.Laplacian(gray, cv2.CV_16S, ksize=3)
Laplacian = cv2.convertScaleAbs(dst)
contour = find_contours(Laplacian) # 提取轮廓点坐标
contour_array = contour[0][:,0,:] # 注意这里只保留区域面积最大的轮廓点坐标
print(contour_array)
ret_np = np.ones(dst.shape, np.uint8) # 创建黑色幕布
ret = cv2.drawContours(ret_np, contour[0], -1, (255, 255, 255), 1) # 绘制白色轮廓
contours_complex = np.empty(contour_array.shape[:-1], dtype=complex)
contours_complex.real = contour_array[:, 0] # 横坐标作为实数部分
contours_complex.imag = contour_array[:, 1] # 纵坐标作为虚数部分
fourier_result = np.fft.fft(contours_complex) # 进行傅里叶变换
# fourier_result = np.fft.fftshift(fourier_result)
descirptor_in_use = truncate_descriptor(fourier_result) # 截短傅里叶描述子
# reconstruct(ret, descirptor_in_use) 截短的重构轮廓
# cv2.imshow("ret", ret)#mine
# cv2.imwrite('E:\\pictures\\s\\ret.png', ret)#mine
return ret, descirptor_in_use, contour, contour_array
def find_contours(Laplacian):
# binaryimg = cv2.Canny(res, 50, 200) #二值化,canny检测
h = cv2.findContours(Laplacian, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) # 寻找轮廓
contour = h[0]
contour = sorted(contour, key=cv2.contourArea, reverse=True) # 对一系列轮廓点坐标按它们围成的区域面积进行排序
return contour
# 截短傅里叶描述子
def truncate_descriptor(fourier_result):
descriptors_in_use = np.fft.fftshift(fourier_result)
# 取中间的MIN_DESCRIPTOR项描述子
center_index = int(len(descriptors_in_use) / 2)
low, high = center_index - int(MIN_DESCRIPTOR / 2), center_index + int(MIN_DESCRIPTOR / 2)
descriptors_in_use = descriptors_in_use[low:high]
descriptors_in_use = np.fft.ifftshift(descriptors_in_use)
return descriptors_in_use
##由傅里叶描述子重建轮廓图
def reconstruct(img, descirptor_in_use):
# descirptor_in_use = truncate_descriptor(fourier_result, degree)
# descirptor_in_use = np.fft.ifftshift(fourier_result)
# descirptor_in_use = truncate_descriptor(fourier_result)
# print(descirptor_in_use)
contour_reconstruct = np.fft.ifft(descirptor_in_use)
contour_reconstruct = np.array([contour_reconstruct.real,
contour_reconstruct.imag])
contour_reconstruct = np.transpose(contour_reconstruct)
contour_reconstruct = np.expand_dims(contour_reconstruct, axis=1)
if contour_reconstruct.min() < 0:
contour_reconstruct -= contour_reconstruct.min()
contour_reconstruct *= img.shape[0] / contour_reconstruct.max()
contour_reconstruct = contour_reconstruct.astype(np.int32, copy=False)
black_np = np.ones(img.shape, np.uint8) # 创建黑色幕布
black = cv2.drawContours(black_np, contour_reconstruct, -1, (255, 255, 255), 1) # 绘制白色轮廓
cv2.imshow("contour_reconstruct", black)
cv2.imwrite('E:\\pictures\\s\\recover.png',black)
return black