├── GUI.py ├── Image ├── Gray │ ├── 5.1.09.tiff │ ├── 5.1.10.tiff │ ├── 5.1.11.tiff │ ├── 5.1.12.tiff │ ├── 5.1.13.tiff │ ├── 5.1.14.tiff │ ├── 5.2.08.tiff │ ├── 5.2.09.tiff │ ├── 5.2.10.tiff │ ├── 5.3.01.tiff │ ├── 5.3.02.tiff │ ├── 7.1.01.tiff │ ├── 7.1.02.tiff │ ├── 7.1.03.tiff │ ├── 7.1.04.tiff │ ├── 7.1.05.tiff │ ├── 7.1.06.tiff │ ├── 7.1.07.tiff │ ├── 7.1.08.tiff │ ├── 7.1.09.tiff │ ├── 7.1.10.tiff │ ├── 7.2.01.tiff │ ├── Baboon.bmp │ ├── Barbara.bmp │ ├── Cameraman.bmp │ ├── Goldhill.bmp │ ├── Lena.bmp │ ├── Peppers.bmp │ └── boat.512.tiff └── RGB │ ├── 4.1.01.tiff │ ├── 4.1.02.tiff │ ├── 4.1.03.tiff │ ├── 4.1.04.tiff │ ├── 4.1.05.tiff │ ├── 4.1.06.tiff │ ├── 4.1.07.tiff │ ├── 4.1.08.tiff │ ├── 4.2.01.tiff │ ├── 4.2.05.tiff │ ├── 4.2.06.tiff │ ├── BaboonRGB.bmp │ ├── LenaRGB.bmp │ ├── PeppersRGB.bmp │ └── eagleRGB.jpg ├── README.md ├── requirements.txt ├── run_me.bat └── utils ├── Canny.py ├── Dog.py ├── FDoG.py ├── __pycache__ ├── Canny.cpython-38.pyc ├── Dog.cpython-38.pyc └── FDoG.cpython-38.pyc └── img_6.png /GUI.py: -------------------------------------------------------------------------------- 1 | import tkinter as tk 2 | from tkinter import filedialog 3 | from matplotlib import pyplot as plt 4 | from matplotlib.figure import Figure 5 | from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg 6 | from utils.Dog import DoG 7 | import os 8 | import cv2 9 | from utils.FDoG import run 10 | import numpy as np 11 | from utils.Canny import NMS 12 | 13 | plt.rcParams['font.sans-serif'] = ['SimHei'] 14 | 15 | 16 | def select_file(): 17 | # 单个文件选择 18 | selected_file_path = filedialog.askopenfilename() # 使用askopenfilename函数选择单个文件 19 | select_path.set(selected_file_path) 20 | 21 | 22 | def EdgeDetection(path, canvas, sigma_c, sigma_m, rho, sobel_size, etf_size): 23 | input_img = path 24 | img = cv2.imread(input_img) 25 | if img.shape[:2] != (1024, 1024): 26 | img = cv2.resize(img, (1024, 1024)) 27 | rgb_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) 28 | grayImage = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 29 | 30 | # Prewitt 31 | kernelx = np.array([[1, 1, 1], [0, 0, 0], [-1, -1, -1]], dtype=int) 32 | kernely = np.array([[-1, 0, 1], [-1, 0, 1], [-1, 0, 1]], dtype=int) 33 | x = cv2.filter2D(grayImage, cv2.CV_16S, kernelx) 34 | y = cv2.filter2D(grayImage, cv2.CV_16S, kernely) 35 | absX = cv2.convertScaleAbs(x) 36 | absY = cv2.convertScaleAbs(y) 37 | Prewitt = cv2.addWeighted(absX, 0.5, absY, 0.5, 0) 38 | 39 | # Sobel 40 | x = cv2.Sobel(grayImage, cv2.CV_16S, 1, 0) 41 | y = cv2.Sobel(grayImage, cv2.CV_16S, 0, 1) 42 | absX = cv2.convertScaleAbs(x) 43 | absY = cv2.convertScaleAbs(y) 44 | Sobel = cv2.addWeighted(absX, 0.5, absY, 0.5, 0) 45 | 46 | # Canny 47 | gaussian = cv2.GaussianBlur(grayImage, (3, 3), 0) 48 | Canny = cv2.Canny(gaussian, 50, 150) 49 | 50 | # Dog 51 | differenced = DoG(grayImage, 25, 4, 1.1, None, 0.1) 52 | 53 | # FDoG 54 | edge = run( 55 | img=grayImage, sobel_size=sobel_size, 56 | etf_iter=6, etf_size=etf_size, 57 | fdog_iter=5, sigma_c=sigma_c, rho=rho, sigma_m=sigma_m, 58 | tau=0.907 59 | ) 60 | 61 | # NMS + FDoG 62 | NMS_ = NMS(edge) 63 | 64 | # 结果列表存储 65 | titles = ['Orignal', 'Prewitt', 'Sobel', 'Canny', 'FDoG', 'NMS+FDoG'] 66 | images = [rgb_img, Prewitt, Sobel, Canny, edge, NMS_] 67 | 68 | # 为便于比较进行反色处理 69 | for i in [1, 2, 3]: 70 | images[i] = cv2.bitwise_not(images[i]) 71 | 72 | # 展示图片&保存图片 73 | filename = os.path.splitext(os.path.split(path)[1])[0] 74 | dirsname = os.path.join('./ans/', filename) 75 | if not os.path.exists(dirsname): 76 | os.makedirs(dirsname) 77 | 78 | for i in range(len(images)): 79 | a = f.add_subplot(2, 3, i+1) 80 | a.clear() 81 | a.imshow(images[i], 'gray') 82 | a.set_xticks([]) 83 | a.set_yticks([]) 84 | a.set_title(titles[i]) 85 | if titles[i] == 'Orignal': 86 | cv2.imwrite(os.path.join(dirsname, f'{titles[i]}.jpg'), cv2.cvtColor(images[i], cv2.COLOR_RGB2BGR)) 87 | else: 88 | cv2.imwrite(os.path.join(dirsname, f'{titles[i]}.jpg'), images[i]) 89 | canvas.draw() 90 | canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=tk.YES) 91 | f.savefig(os.path.join(dirsname, f'ALL.jpg'), dpi = 600) 92 | print(f'ans saved to {dirsname}') 93 | 94 | 95 | if __name__ == "__main__": 96 | root = tk.Tk() 97 | select_path = tk.StringVar() 98 | sigma_c = tk.DoubleVar() 99 | sigma_c.set(1.0) 100 | etf_size = tk.IntVar() 101 | etf_size.set(7) 102 | sobel_size = tk.IntVar() 103 | sobel_size.set(5) 104 | rho = tk.DoubleVar() 105 | rho.set(0.997) 106 | sigma_m = tk.DoubleVar() 107 | sigma_m.set(3.0) 108 | f = Figure(figsize=(5, 4), dpi=100) 109 | canvas = FigureCanvasTkAgg(f, master=root) 110 | 111 | tk.Label(root, text="文件路径:").pack(side='top', anchor='nw') 112 | tk.Entry(root, textvariable=select_path).pack(side='top', anchor='n', fill='x') 113 | 114 | tk.Button(root, text="选择图片", command=select_file).pack(side='top', anchor='ne') 115 | 116 | tk.Label(root, text="sigma_c(another's standard variance will be set to1.6 * sigma_c)").pack(side='top', anchor='nw') 117 | tk.Entry(root, textvariable=sigma_c).pack(side='top', anchor='n', fill='x') 118 | 119 | tk.Label(root, text="sigma_m").pack(side='top', anchor='nw') 120 | tk.Entry(root, textvariable=sigma_m).pack(side='top', anchor='n', fill='x') 121 | 122 | tk.Label(root, text="rho").pack(side='top', anchor='nw') 123 | tk.Entry(root, textvariable=rho).pack(side='top', anchor='n', fill='x') 124 | 125 | tk.Label(root, text="etf_size").pack(side='top', anchor='nw') 126 | tk.Entry(root, textvariable=etf_size).pack(side='top', anchor='n', fill='x') 127 | 128 | tk.Label(root, text="sobel_size").pack(side='top', anchor='nw') 129 | tk.Entry(root, textvariable=sobel_size).pack(side='top', anchor='n', fill='x') 130 | 131 | tk.Button(root, text="边缘提取", command=lambda: EdgeDetection(select_path.get(), canvas, sigma_c.get(), sigma_m.get(), 132 | rho.get(), sobel_size.get(), etf_size.get())).pack() 133 | root.mainloop() 134 | -------------------------------------------------------------------------------- /Image/Gray/5.1.09.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mq-yuan/EdgeDetection-for-ImageProcressing/8461efa5eba9cdd58a1fd8a571b392bd2f06b8a1/Image/Gray/5.1.09.tiff -------------------------------------------------------------------------------- /Image/Gray/5.1.10.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mq-yuan/EdgeDetection-for-ImageProcressing/8461efa5eba9cdd58a1fd8a571b392bd2f06b8a1/Image/Gray/5.1.10.tiff -------------------------------------------------------------------------------- /Image/Gray/5.1.11.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mq-yuan/EdgeDetection-for-ImageProcressing/8461efa5eba9cdd58a1fd8a571b392bd2f06b8a1/Image/Gray/5.1.11.tiff -------------------------------------------------------------------------------- /Image/Gray/5.1.12.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mq-yuan/EdgeDetection-for-ImageProcressing/8461efa5eba9cdd58a1fd8a571b392bd2f06b8a1/Image/Gray/5.1.12.tiff -------------------------------------------------------------------------------- /Image/Gray/5.1.13.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mq-yuan/EdgeDetection-for-ImageProcressing/8461efa5eba9cdd58a1fd8a571b392bd2f06b8a1/Image/Gray/5.1.13.tiff -------------------------------------------------------------------------------- /Image/Gray/5.1.14.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mq-yuan/EdgeDetection-for-ImageProcressing/8461efa5eba9cdd58a1fd8a571b392bd2f06b8a1/Image/Gray/5.1.14.tiff -------------------------------------------------------------------------------- /Image/Gray/5.2.08.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mq-yuan/EdgeDetection-for-ImageProcressing/8461efa5eba9cdd58a1fd8a571b392bd2f06b8a1/Image/Gray/5.2.08.tiff -------------------------------------------------------------------------------- /Image/Gray/5.2.09.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mq-yuan/EdgeDetection-for-ImageProcressing/8461efa5eba9cdd58a1fd8a571b392bd2f06b8a1/Image/Gray/5.2.09.tiff -------------------------------------------------------------------------------- /Image/Gray/5.2.10.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mq-yuan/EdgeDetection-for-ImageProcressing/8461efa5eba9cdd58a1fd8a571b392bd2f06b8a1/Image/Gray/5.2.10.tiff -------------------------------------------------------------------------------- /Image/Gray/5.3.01.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mq-yuan/EdgeDetection-for-ImageProcressing/8461efa5eba9cdd58a1fd8a571b392bd2f06b8a1/Image/Gray/5.3.01.tiff -------------------------------------------------------------------------------- /Image/Gray/5.3.02.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mq-yuan/EdgeDetection-for-ImageProcressing/8461efa5eba9cdd58a1fd8a571b392bd2f06b8a1/Image/Gray/5.3.02.tiff -------------------------------------------------------------------------------- /Image/Gray/7.1.01.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mq-yuan/EdgeDetection-for-ImageProcressing/8461efa5eba9cdd58a1fd8a571b392bd2f06b8a1/Image/Gray/7.1.01.tiff -------------------------------------------------------------------------------- /Image/Gray/7.1.02.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mq-yuan/EdgeDetection-for-ImageProcressing/8461efa5eba9cdd58a1fd8a571b392bd2f06b8a1/Image/Gray/7.1.02.tiff -------------------------------------------------------------------------------- /Image/Gray/7.1.03.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mq-yuan/EdgeDetection-for-ImageProcressing/8461efa5eba9cdd58a1fd8a571b392bd2f06b8a1/Image/Gray/7.1.03.tiff -------------------------------------------------------------------------------- /Image/Gray/7.1.04.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mq-yuan/EdgeDetection-for-ImageProcressing/8461efa5eba9cdd58a1fd8a571b392bd2f06b8a1/Image/Gray/7.1.04.tiff -------------------------------------------------------------------------------- /Image/Gray/7.1.05.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mq-yuan/EdgeDetection-for-ImageProcressing/8461efa5eba9cdd58a1fd8a571b392bd2f06b8a1/Image/Gray/7.1.05.tiff -------------------------------------------------------------------------------- /Image/Gray/7.1.06.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mq-yuan/EdgeDetection-for-ImageProcressing/8461efa5eba9cdd58a1fd8a571b392bd2f06b8a1/Image/Gray/7.1.06.tiff -------------------------------------------------------------------------------- /Image/Gray/7.1.07.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mq-yuan/EdgeDetection-for-ImageProcressing/8461efa5eba9cdd58a1fd8a571b392bd2f06b8a1/Image/Gray/7.1.07.tiff -------------------------------------------------------------------------------- /Image/Gray/7.1.08.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mq-yuan/EdgeDetection-for-ImageProcressing/8461efa5eba9cdd58a1fd8a571b392bd2f06b8a1/Image/Gray/7.1.08.tiff -------------------------------------------------------------------------------- /Image/Gray/7.1.09.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mq-yuan/EdgeDetection-for-ImageProcressing/8461efa5eba9cdd58a1fd8a571b392bd2f06b8a1/Image/Gray/7.1.09.tiff -------------------------------------------------------------------------------- /Image/Gray/7.1.10.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mq-yuan/EdgeDetection-for-ImageProcressing/8461efa5eba9cdd58a1fd8a571b392bd2f06b8a1/Image/Gray/7.1.10.tiff -------------------------------------------------------------------------------- /Image/Gray/7.2.01.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mq-yuan/EdgeDetection-for-ImageProcressing/8461efa5eba9cdd58a1fd8a571b392bd2f06b8a1/Image/Gray/7.2.01.tiff -------------------------------------------------------------------------------- /Image/Gray/Baboon.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mq-yuan/EdgeDetection-for-ImageProcressing/8461efa5eba9cdd58a1fd8a571b392bd2f06b8a1/Image/Gray/Baboon.bmp -------------------------------------------------------------------------------- /Image/Gray/Barbara.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mq-yuan/EdgeDetection-for-ImageProcressing/8461efa5eba9cdd58a1fd8a571b392bd2f06b8a1/Image/Gray/Barbara.bmp -------------------------------------------------------------------------------- /Image/Gray/Cameraman.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mq-yuan/EdgeDetection-for-ImageProcressing/8461efa5eba9cdd58a1fd8a571b392bd2f06b8a1/Image/Gray/Cameraman.bmp -------------------------------------------------------------------------------- /Image/Gray/Goldhill.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mq-yuan/EdgeDetection-for-ImageProcressing/8461efa5eba9cdd58a1fd8a571b392bd2f06b8a1/Image/Gray/Goldhill.bmp -------------------------------------------------------------------------------- /Image/Gray/Lena.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mq-yuan/EdgeDetection-for-ImageProcressing/8461efa5eba9cdd58a1fd8a571b392bd2f06b8a1/Image/Gray/Lena.bmp -------------------------------------------------------------------------------- /Image/Gray/Peppers.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mq-yuan/EdgeDetection-for-ImageProcressing/8461efa5eba9cdd58a1fd8a571b392bd2f06b8a1/Image/Gray/Peppers.bmp -------------------------------------------------------------------------------- /Image/Gray/boat.512.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mq-yuan/EdgeDetection-for-ImageProcressing/8461efa5eba9cdd58a1fd8a571b392bd2f06b8a1/Image/Gray/boat.512.tiff -------------------------------------------------------------------------------- /Image/RGB/4.1.01.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mq-yuan/EdgeDetection-for-ImageProcressing/8461efa5eba9cdd58a1fd8a571b392bd2f06b8a1/Image/RGB/4.1.01.tiff -------------------------------------------------------------------------------- /Image/RGB/4.1.02.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mq-yuan/EdgeDetection-for-ImageProcressing/8461efa5eba9cdd58a1fd8a571b392bd2f06b8a1/Image/RGB/4.1.02.tiff -------------------------------------------------------------------------------- /Image/RGB/4.1.03.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mq-yuan/EdgeDetection-for-ImageProcressing/8461efa5eba9cdd58a1fd8a571b392bd2f06b8a1/Image/RGB/4.1.03.tiff -------------------------------------------------------------------------------- /Image/RGB/4.1.04.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mq-yuan/EdgeDetection-for-ImageProcressing/8461efa5eba9cdd58a1fd8a571b392bd2f06b8a1/Image/RGB/4.1.04.tiff -------------------------------------------------------------------------------- /Image/RGB/4.1.05.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mq-yuan/EdgeDetection-for-ImageProcressing/8461efa5eba9cdd58a1fd8a571b392bd2f06b8a1/Image/RGB/4.1.05.tiff -------------------------------------------------------------------------------- /Image/RGB/4.1.06.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mq-yuan/EdgeDetection-for-ImageProcressing/8461efa5eba9cdd58a1fd8a571b392bd2f06b8a1/Image/RGB/4.1.06.tiff -------------------------------------------------------------------------------- /Image/RGB/4.1.07.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mq-yuan/EdgeDetection-for-ImageProcressing/8461efa5eba9cdd58a1fd8a571b392bd2f06b8a1/Image/RGB/4.1.07.tiff -------------------------------------------------------------------------------- /Image/RGB/4.1.08.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mq-yuan/EdgeDetection-for-ImageProcressing/8461efa5eba9cdd58a1fd8a571b392bd2f06b8a1/Image/RGB/4.1.08.tiff -------------------------------------------------------------------------------- /Image/RGB/4.2.01.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mq-yuan/EdgeDetection-for-ImageProcressing/8461efa5eba9cdd58a1fd8a571b392bd2f06b8a1/Image/RGB/4.2.01.tiff -------------------------------------------------------------------------------- /Image/RGB/4.2.05.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mq-yuan/EdgeDetection-for-ImageProcressing/8461efa5eba9cdd58a1fd8a571b392bd2f06b8a1/Image/RGB/4.2.05.tiff -------------------------------------------------------------------------------- /Image/RGB/4.2.06.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mq-yuan/EdgeDetection-for-ImageProcressing/8461efa5eba9cdd58a1fd8a571b392bd2f06b8a1/Image/RGB/4.2.06.tiff -------------------------------------------------------------------------------- /Image/RGB/BaboonRGB.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mq-yuan/EdgeDetection-for-ImageProcressing/8461efa5eba9cdd58a1fd8a571b392bd2f06b8a1/Image/RGB/BaboonRGB.bmp -------------------------------------------------------------------------------- /Image/RGB/LenaRGB.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mq-yuan/EdgeDetection-for-ImageProcressing/8461efa5eba9cdd58a1fd8a571b392bd2f06b8a1/Image/RGB/LenaRGB.bmp -------------------------------------------------------------------------------- /Image/RGB/PeppersRGB.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mq-yuan/EdgeDetection-for-ImageProcressing/8461efa5eba9cdd58a1fd8a571b392bd2f06b8a1/Image/RGB/PeppersRGB.bmp -------------------------------------------------------------------------------- /Image/RGB/eagleRGB.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mq-yuan/EdgeDetection-for-ImageProcressing/8461efa5eba9cdd58a1fd8a571b392bd2f06b8a1/Image/RGB/eagleRGB.jpg -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![](https://typora-ilgzh.oss-cn-beijing.aliyuncs.com/202303241427863.jpg) 2 | 3 | # 边缘检测 4 | 5 | ## 介绍 6 | 本次实验使用python实现了Prewitt、Sobel、Canny、FDoG和使用非极大值约束得FDoG这五种边缘检测方式,并制作了GUI便于使用。为使效果对比更加明显,对Prewitt、Sobel、Canny的输出结果进行反色处理。 7 | 8 | 仅作学习参考,请不要直接抄袭,只有自己完成相应实验,才能真正地学习到知识。 9 | 10 | ## 环境依赖 11 | - `pip install -r requirements.txt`. 12 | 13 | ## 实验测试 14 | 在windows系统且确保已安装python3的情况下,点击`run_me.bat`文件可直接运行。 15 | 16 | 或者可以使用 `python ./GUI.py` .命令 17 | 18 | ## 文件架构 19 | 20 | 文件中已附带`Image`文件夹如下: 21 | 22 | ```py 23 | Image 24 | ├─RGB # 存放图像处理常用RGB类型测试图 25 | | ├─4.1.01.tiff 26 | | ├─4.1.02.tiff 27 | | ...... 28 | | ├─LenaRGB.bmp 29 | | └PeppersRGB.bmp 30 | ├─Personal # 个人图像 31 | | ├─1_1.jpg 32 | | ├─1_2.png 33 | | ├─1_3.jpg 34 | | └1_4.jpg 35 | ├─Gray # 存放图像处理常用灰度测试图 36 | | ├─5.1.09.tiff 37 | | ├─5.1.10.tiff 38 | | ...... 39 | | ├─Lena.bmp 40 | | └Peppers.bmp 41 | ``` 42 | 43 | 点击“选择图片”选择测试图片后点击“边缘提取”进行边缘提取,程序将自动上述提到的五种方法和原图展示到屏幕上,并保存至`./ans/xxx`文件夹中,关闭窗口程序结束。 44 | 45 | ## Citations 46 | ``` 47 | @inproceedings{Kang2007CoherentLD, 48 | title={Coherent line drawing}, 49 | author={Henry Kang and Seungyong Lee and Charles K. Chui}, 50 | booktitle={International Symposium on Non-Photorealistic Animation and Rendering}, 51 | year={2007} 52 | } 53 | ``` 54 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mq-yuan/EdgeDetection-for-ImageProcressing/8461efa5eba9cdd58a1fd8a571b392bd2f06b8a1/requirements.txt -------------------------------------------------------------------------------- /run_me.bat: -------------------------------------------------------------------------------- 1 | @pip install -r requirements.txt 2 | @python ./GUI.py 3 | @pause -------------------------------------------------------------------------------- /utils/Canny.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import cv2 3 | import copy 4 | 5 | 6 | def gradients(new_gray): 7 | W, H = new_gray.shape 8 | dx = np.zeros([W - 1, H - 1]) 9 | dy = np.zeros([W - 1, H - 1]) 10 | M = np.zeros([W - 1, H - 1]) 11 | theta = np.zeros([W - 1, H - 1]) 12 | 13 | for i in range(W - 1): 14 | for j in range(H - 1): 15 | dx[i, j] = new_gray[i + 1, j] - new_gray[i, j] 16 | dy[i, j] = new_gray[i, j + 1] - new_gray[i, j] 17 | M[i, j] = np.sqrt(np.square(dx[i, j]) + np.square(dy[i, j])) # 图像梯度幅值作为图像强度值 18 | theta[i, j] = np.arctan(dx[i, j] / (dy[i, j] + 0.000000001)) # 计算 slope θ - artan(dx/dy) 19 | 20 | return dx, dy, M, theta 21 | 22 | 23 | def NMS(img): 24 | ans = copy.deepcopy(img) 25 | h, w = img.shape 26 | for i in range(0, h - 1): 27 | for j in range(0, w - 1): 28 | if np.sum(img[i:i + 2, j:j + 2]) == 0: 29 | ans[i, j] = 0 30 | else: 31 | ans[i, j] = 255 32 | return ans 33 | 34 | 35 | def NMS_(M, dx, dy): 36 | d = np.copy(M) 37 | W, H = M.shape 38 | NMS = np.copy(d) 39 | NMS[0, :] = NMS[W - 1, :] = NMS[:, 0] = NMS[:, H - 1] = 0 40 | 41 | for i in range(1, W - 1): 42 | for j in range(1, H - 1): 43 | 44 | # 如果当前梯度为0,该点就不是比边缘点 45 | if M[i, j] == 0: 46 | NMS[i, j] = 0 47 | 48 | else: 49 | gradX = dx[i, j] # 当前点 x 方向导数 50 | gradY = dy[i, j] # 当前点 y 方向导数 51 | gradTemp = d[i, j] # 当前梯度点 52 | 53 | # 如果 y 方向梯度值比较大,说明导数方向趋向于 y 分量 54 | if np.abs(gradY) > np.abs(gradX): 55 | weight = np.abs(gradX) / np.abs(gradY) # 权重 56 | grad2 = d[i - 1, j] 57 | grad4 = d[i + 1, j] 58 | 59 | # 如果 x, y 方向导数符号一致 60 | # 像素点位置关系 61 | # g1 g2 62 | # c 63 | # g4 g3 64 | if gradX * gradY > 0: 65 | grad1 = d[i - 1, j - 1] 66 | grad3 = d[i + 1, j + 1] 67 | 68 | # 如果 x,y 方向导数符号相反 69 | # 像素点位置关系 70 | # g2 g1 71 | # c 72 | # g3 g4 73 | else: 74 | grad1 = d[i - 1, j + 1] 75 | grad3 = d[i + 1, j - 1] 76 | 77 | # 如果 x 方向梯度值比较大 78 | else: 79 | weight = np.abs(gradY) / np.abs(gradX) 80 | grad2 = d[i, j - 1] 81 | grad4 = d[i, j + 1] 82 | 83 | # 如果 x, y 方向导数符号一致 84 | # 像素点位置关系 85 | # g1 86 | # g2 c g4 87 | # g3 88 | if gradX * gradY > 0: 89 | grad1 = d[i - 1, j - 1] 90 | grad3 = d[i + 1, j + 1] 91 | 92 | # 如果 x,y 方向导数符号相反 93 | # 像素点位置关系 94 | # g3 95 | # g2 c g4 96 | # g1 97 | else: 98 | grad1 = d[i + 1, j - 1] 99 | grad3 = d[i - 1, j + 1] 100 | 101 | # 利用 grad1-grad4 对梯度进行插值 102 | gradTemp1 = weight * grad1 + (1 - weight) * grad2 103 | gradTemp2 = weight * grad3 + (1 - weight) * grad4 104 | 105 | # 当前像素的梯度是局部的最大值,可能是边缘点 106 | if gradTemp >= gradTemp1 and gradTemp >= gradTemp2: 107 | NMS[i, j] = gradTemp 108 | 109 | else: 110 | # 不可能是边缘点 111 | NMS[i, j] = 0 112 | 113 | return NMS 114 | 115 | 116 | def smooth(img_gray): 117 | # 生成高斯滤波器 118 | """ 119 | 要生成一个 (2k+1)x(2k+1) 的高斯滤波器,滤波器的各个元素计算公式如下: 120 | 121 | H[i, j] = (1/(2*pi*sigma**2))*exp(-1/2*sigma**2((i-k-1)**2 + (j-k-1)**2)) 122 | """ 123 | sigma1 = sigma2 = 1.4 124 | gau_sum = 0 125 | gaussian = np.zeros([5, 5]) 126 | for i in range(5): 127 | for j in range(5): 128 | gaussian[i, j] = np.exp((-1 / (2 * sigma1 * sigma2)) * (np.square(i - 3) 129 | + np.square(j - 3))) / (2 * np.pi * sigma1 * sigma2) 130 | gau_sum = gau_sum + gaussian[i, j] 131 | 132 | # 归一化处理 133 | gaussian = gaussian / gau_sum 134 | 135 | # 高斯滤波 136 | W, H = img_gray.shape 137 | new_gray = np.zeros([W - 5, H - 5]) 138 | 139 | for i in range(W - 5): 140 | for j in range(H - 5): 141 | new_gray[i, j] = np.sum(img_gray[i:i + 5, j:j + 5] * gaussian) 142 | 143 | return new_gray 144 | 145 | 146 | def double_threshold(NMS): 147 | W, H = NMS.shape 148 | DT = np.zeros([W, H]) 149 | 150 | # 定义高低阈值 151 | TL = 0.1 * np.max(NMS) 152 | TH = 0.3 * np.max(NMS) 153 | 154 | for i in range(1, W - 1): 155 | for j in range(1, H - 1): 156 | if NMS[i, j] < TL: 157 | DT[i, j] = 0 158 | 159 | elif NMS[i, j] > TH: 160 | DT[i, j] = 1 161 | 162 | # 163 | elif (NMS[i - 1, j - 1:j + 1] < TH).any() or (NMS[i + 1, j - 1:j + 1].any() 164 | or (NMS[i, [j - 1, j + 1]] < TH).any()): 165 | DT[i, j] = 1 166 | 167 | return DT 168 | -------------------------------------------------------------------------------- /utils/Dog.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import cv2 3 | 4 | def genGaussianKernel(ksize, sigma): 5 | half_ksize = ksize // 2 6 | C = 2 * np.pi * sigma * sigma 7 | x = y = np.linspace(-half_ksize, half_ksize, ksize) 8 | x, y = np.meshgrid(x, y) 9 | kernel = np.exp(-(x ** 2 + y ** 2) / (2 * sigma ** 2)) / C 10 | return kernel 11 | 12 | def zerosCrossing(src, thresh): 13 | dsize = (src.shape[1], src.shape[0]) 14 | M = np.array([[1, 0, -1], [0, 1, 0]], dtype=np.float32) 15 | shift_left = cv2.warpAffine(src, M, dsize) 16 | M = np.array([[1, 0, 1], [0, 1, 0]], dtype=np.float32) 17 | shift_right = cv2.warpAffine(src, M, dsize) 18 | 19 | M = np.array([[1, 0, 0], [0, 1, -1]], dtype=np.float32) 20 | shift_up = cv2.warpAffine(src, M, dsize) 21 | M = np.array([[1, 0, 0], [0, 1, 1]], dtype=np.float32) 22 | shift_down = cv2.warpAffine(src, M, dsize) 23 | 24 | M = np.array([[1, 0, 1], [0, 1, 1]], dtype=np.float32) 25 | shift_right_down = cv2.warpAffine(src, M, dsize) 26 | M = np.array([[1, 0, -1], [0, 1, -1]], dtype=np.float32) 27 | shift_left_up = cv2.warpAffine(src, M, dsize) 28 | 29 | M = np.array([[1, 0, 1], [0, 1, -1]], dtype=np.float32) 30 | shift_right_up = cv2.warpAffine(src, M, dsize) 31 | M = np.array([[1, 0, -1], [0, 1, 1]], dtype=np.float32) 32 | shift_left_down = cv2.warpAffine(src, M, dsize) 33 | 34 | shift_left_right_sign = (shift_left * shift_right) 35 | shift_up_down_sign = (shift_up * shift_down) 36 | shift_rd_lu_sign = (shift_right_down * shift_left_up) 37 | shift_ru_ld_sign = (shift_right_up * shift_left_down) 38 | 39 | shift_left_right_norm = abs(shift_left - shift_right) 40 | shift_up_down_norm = abs(shift_up - shift_down) 41 | shift_rd_lu_norm = abs(shift_right_down - shift_left_up) 42 | shift_ru_ld_norm = abs(shift_right_up - shift_left_down) 43 | 44 | candidate_zero_crossing = \ 45 | ((shift_left_right_sign < 0) & (shift_left_right_norm > thresh)).astype('uint8') +\ 46 | ((shift_up_down_sign < 0) & (shift_up_down_norm > thresh)).astype('uint8') + \ 47 | ((shift_rd_lu_sign < 0) & (shift_rd_lu_norm > thresh)).astype('uint8') + \ 48 | ((shift_ru_ld_sign < 0) & (shift_ru_ld_norm > thresh)).astype('uint8') 49 | 50 | ResImg = np.zeros(shape=src.shape, dtype=np.uint8) 51 | ResImg[candidate_zero_crossing >= 2] = 255 52 | 53 | return ResImg 54 | 55 | 56 | def DoG(src, ksize, sigma, k, thresh=None, alpha=0.01): 57 | sigma2 = sigma / k 58 | kernel_1 = genGaussianKernel(ksize=ksize, sigma=sigma) 59 | kernel_2 = genGaussianKernel(ksize=ksize, sigma=sigma2) 60 | kernel = kernel_1 - kernel_2 61 | 62 | DoG_img = cv2.filter2D(src=src, ddepth=cv2.CV_32FC1, kernel=kernel) 63 | if thresh is None: 64 | thresh = abs(DoG_img).max() * alpha 65 | edge_image = zerosCrossing(src=DoG_img, thresh=thresh) 66 | return edge_image -------------------------------------------------------------------------------- /utils/FDoG.py: -------------------------------------------------------------------------------- 1 | import cv2 as cv 2 | import numpy as np 3 | 4 | 5 | def find_neighbors(x, ksize, s, out_h, out_w): 6 | """ Get sliding windows using numpy's stride tricks. """ 7 | in_c, in_h, in_w = x.shape 8 | shape = (out_h, out_w, in_c, ksize, ksize) 9 | itemsize = x.itemsize 10 | strides = ( 11 | s * in_w * itemsize, 12 | s * itemsize, 13 | in_w * in_h * itemsize, 14 | in_w * itemsize, 15 | itemsize 16 | ) 17 | return np.lib.stride_tricks.as_strided(x, shape=shape, 18 | strides=strides) 19 | 20 | 21 | def refine_flow(flow, mag, ksize): 22 | """ Refine edge tangent flow based on paper's 23 | equation. """ 24 | _, h, w = flow.shape 25 | 26 | # do padding 27 | p = ksize // 2 28 | flow = np.pad(flow, ((0, 0), (p, p), (p, p))) 29 | mag = np.pad(mag, ((0, 0), (p, p), (p, p))) 30 | 31 | # neighbors of each tangent vector in each window 32 | flow_neighbors = find_neighbors(flow, ksize, 33 | s=1, out_h=h, out_w=w) 34 | 35 | # centural tangent vector in each window 36 | flow_me = flow_neighbors[..., ksize // 2, ksize // 2] 37 | flow_me = flow_me[..., np.newaxis, np.newaxis] 38 | 39 | # compute dot 40 | dots = np.sum(flow_neighbors * flow_me, axis=2, 41 | keepdims=True) 42 | 43 | # compute phi 44 | phi = np.where(dots > 0, 1, -1) 45 | 46 | # compute wd, weight of direction 47 | wd = np.abs(dots) 48 | 49 | # compute wm, weight of magnitude 50 | mag_neighbors = find_neighbors(mag, ksize, 51 | s=1, out_h=h, out_w=w) 52 | mag_me = mag_neighbors[..., ksize // 2, ksize // 2] 53 | mag_me = mag_me[..., np.newaxis, np.newaxis] 54 | wm = (1 + np.tanh(mag_neighbors - mag_me)) / 2 55 | 56 | # compute ws, spatial weight 57 | ws = np.ones_like(wm) 58 | x, y = np.meshgrid(np.arange(ksize), np.arange(ksize)) 59 | cx, cy = ksize // 2, ksize // 2 60 | dist = np.sqrt((x - cx) ** 2 + (y - cy) ** 2)[np.newaxis, ...] 61 | ws[:, :, dist >= ksize // 2] = 0 62 | 63 | # update flow 64 | flow = np.sum(phi * flow_neighbors * ws * wm * wd, 65 | axis=(3, 4)) 66 | flow = np.transpose(flow, axes=(2, 0, 1)) 67 | 68 | # normalize flow 69 | norm = np.sqrt(np.sum(flow ** 2, axis=0)) 70 | mask = norm != 0 71 | flow[:, mask] /= norm[mask] 72 | 73 | return flow 74 | 75 | 76 | def guass(x, sigma): 77 | return np.exp(-(x ** 2) / (2 * sigma ** 2)) / (np.sqrt(2 * np.pi) * sigma) 78 | 79 | 80 | def make_gauss_filter(sigma, threshold=0.001): 81 | i = 0 82 | while guass(i, sigma) >= threshold: 83 | i = i + 1 84 | 85 | return guass(np.arange(-i, i + 1), sigma).astype('float32') 86 | 87 | 88 | def shrink_array(a, center, width): 89 | """ Shrink an 1-D array with respect to center 90 | and width. """ 91 | return a[-width + center: width + 1 + center] 92 | 93 | 94 | def detect_edge(img, flow, thresh, sigma_c, rho, 95 | sigma_m, tau): 96 | """ Detect edge on input image based of edge tangent 97 | flow, the following code is messy ... """ 98 | h, w = img.shape 99 | # normalize input image 100 | img = img / 255.0 101 | 102 | # create two gauss filter 103 | gauss_c = make_gauss_filter(sigma_c, threshold=thresh) 104 | gauss_s = make_gauss_filter(sigma_c * 1.6, 105 | threshold=thresh) 106 | 107 | # shrink filter to the same size 108 | w_gauss_c, w_gauss_s = len(gauss_c) // 2, len(gauss_s) // 2 109 | w_fdog = min(w_gauss_c, w_gauss_s) 110 | gauss_c = shrink_array(gauss_c, w_gauss_c, w_fdog) 111 | gauss_s = shrink_array(gauss_s, w_gauss_s, w_fdog) 112 | 113 | # do padding because some vectorized operations 114 | # may accross the boundary of image 115 | img = np.pad(img, 116 | ((w_fdog, w_fdog), (w_fdog, w_fdog))) 117 | 118 | # start coords of each pixel (shifted by width of filter) 119 | sx, sy = np.meshgrid(np.arange(w), np.arange(h)) 120 | start = np.concatenate((sx[np.newaxis, ...], 121 | sy[np.newaxis, ...]), axis=0) + w_fdog 122 | 123 | # steps of each pixel 124 | steps = np.arange(-w_fdog, w_fdog + 1) 125 | steps = steps.reshape((-1, 1, 1, 1)) 126 | steps = np.repeat(steps, repeats=2, axis=1) 127 | 128 | # rotate flow to get gradient 129 | grad = np.empty_like(flow) 130 | grad[0, ...] = flow[1, ...] 131 | grad[1, ...] = -flow[0, ...] 132 | 133 | # take steps along the gradient 134 | xy = start + (steps * grad) 135 | ixy = np.round(xy).astype('int32') 136 | ix, iy = np.split(ixy, indices_or_sections=2, axis=1) 137 | ix = ix.reshape(2 * w_fdog + 1, h, w) 138 | iy = iy.reshape(2 * w_fdog + 1, h, w) 139 | 140 | # neighbors of each pixel along the gradient 141 | neighbors = img[iy, ix] 142 | 143 | # apply dog filter in gradient's direction 144 | gauss_c = gauss_c.reshape(2 * w_fdog + 1, 1, 1) 145 | img_gauss_c = np.sum(gauss_c * neighbors, axis=0) / np.sum(gauss_c) 146 | 147 | gauss_s = gauss_s.reshape(2 * w_fdog + 1, 1, 1) 148 | img_gauss_s = np.sum(gauss_s * neighbors, axis=0) / np.sum(gauss_s) 149 | img_fdog = img_gauss_c - rho * img_gauss_s 150 | 151 | # remove those pixels with zero gradient 152 | zero_grad_mask = np.logical_and( 153 | grad[0, ...] == 0, grad[1, ...] == 0) 154 | img_fdog[zero_grad_mask] = np.max(img_fdog) 155 | 156 | # make gauss filter along tangent vector 157 | gauss_m = make_gauss_filter(sigma_m) 158 | w_gauss_m = len(gauss_m) // 2 159 | 160 | # initialize with a negative weight for coding's convenience 161 | edge = -gauss_m[w_gauss_m] * img_fdog 162 | weight_acc = np.full_like(img_fdog, 163 | fill_value=-gauss_m[w_gauss_m]) 164 | 165 | # do padding 166 | img_fdog = np.pad(img_fdog, 167 | ((w_gauss_m, w_gauss_m), (w_gauss_m, w_gauss_m))) 168 | zero_grad_mask = np.pad(zero_grad_mask, 169 | ((w_gauss_m, w_gauss_m), (w_gauss_m, w_gauss_m))) 170 | flow = np.pad(flow, ((0, 0), 171 | (w_gauss_m, w_gauss_m), (w_gauss_m, w_gauss_m))) 172 | 173 | # start coords of each pixcel 174 | sx, sy = np.meshgrid(np.arange(w), np.arange(h)) 175 | sx += w_gauss_m 176 | sy += w_gauss_m 177 | 178 | # forward mask, indicate whether a pixel need to keep 179 | # going along tangent vector or not 180 | forward_mask = np.full(shape=(h, w), fill_value=True, 181 | dtype='bool') 182 | 183 | # convert dtype from integer to float for accumulating 184 | # steps along tangent vector 185 | x = sx.astype('float32') 186 | y = sy.astype('float32') 187 | ix, iy = np.round(x).astype('int32'), np.round(y).astype('int32') 188 | 189 | # start 190 | for i in range(w_gauss_m + 1): 191 | # get neighbors of each pixel w.r.t its coordinate 192 | neighbors = img_fdog[iy, ix] 193 | 194 | # multiply weight, ignore those pixels who stopped 195 | weight = gauss_m[w_gauss_m + i] 196 | edge[forward_mask] += (neighbors * weight)[forward_mask] 197 | weight_acc[forward_mask] += weight 198 | 199 | # take a step along tangent vector w.r.t coordinate 200 | x += flow[0, iy, ix] 201 | y += flow[1, iy, ix] 202 | 203 | # update coordinates 204 | ix, iy = np.round(x).astype('int32'), np.round(y).astype('int32') 205 | 206 | # update each pixels' status 207 | none_zero_mask = np.logical_not( 208 | zero_grad_mask[iy, ix]) 209 | forward_mask = np.logical_and( 210 | forward_mask, none_zero_mask) 211 | 212 | # going along the reversed tangent vector 213 | forward_mask = np.full(shape=(h, w), fill_value=True, 214 | dtype='bool') 215 | x = sx.astype('float32') 216 | y = sy.astype('float32') 217 | ix, iy = np.round(x).astype('int32'), np.round(y).astype('int32') 218 | for i in range(w_gauss_m + 1): 219 | neighbor = img_fdog[iy, ix] 220 | 221 | weight = gauss_m[w_gauss_m - i] 222 | edge[forward_mask] += (neighbor * weight)[forward_mask] 223 | weight_acc[forward_mask] += weight 224 | 225 | # take a step 226 | x -= flow[0, iy, ix] 227 | y -= flow[1, iy, ix] 228 | ix, iy = np.round(x).astype('int32'), np.round(y).astype('int32') 229 | 230 | none_zero_mask = np.logical_not( 231 | zero_grad_mask[iy, ix]) 232 | forward_mask = np.logical_and( 233 | forward_mask, none_zero_mask) 234 | 235 | # postprocess 236 | edge /= weight_acc 237 | edge[edge > 0] = 1 238 | edge[edge <= 0] = 1 + np.tanh(edge[edge <= 0]) 239 | edge = (edge - np.min(edge)) / (np.max(edge) - np.min(edge)) 240 | 241 | # binarize 242 | edge[edge < tau] = 0 243 | edge[edge >= tau] = 255 244 | return edge.astype('uint8') 245 | 246 | 247 | def initialze_flow(img, sobel_size): 248 | """ Initialize edge tangent flow, contains the 249 | following steps: 250 | (1) normalize input image 251 | (2) compute gradient using sobel operator 252 | (3) compute gradient magnitude 253 | (4) normalize gradient and magnitude 254 | (5) rotate gradient to get tanget vector 255 | """ 256 | img = cv.normalize(img, dst=None, alpha=0.0, beta=1.0, 257 | norm_type=cv.NORM_MINMAX, dtype=cv.CV_32FC1) 258 | 259 | # compute gradient using sobel and magtitude 260 | grad_x = cv.Sobel(img, cv.CV_32FC1, 1, 0, 261 | ksize=sobel_size) 262 | grad_y = cv.Sobel(img, cv.CV_32FC1, 0, 1, 263 | ksize=sobel_size) 264 | mag = np.sqrt(grad_x ** 2 + grad_y ** 2) 265 | 266 | # normalize gradient 267 | mask = mag != 0 268 | grad_x[mask] /= mag[mask] 269 | grad_y[mask] /= mag[mask] 270 | 271 | # normalize magnitude 272 | mag = cv.normalize(mag, dst=None, alpha=0.0, beta=1.0, 273 | norm_type=cv.NORM_MINMAX) 274 | 275 | # rotate gradient and get tangent vector 276 | flow_x, flow_y = -grad_y, grad_x 277 | 278 | # expand dimension in axis=0 for vectorizing 279 | flow = np.concatenate((flow_x[np.newaxis, ...], 280 | flow_y[np.newaxis, ...]), axis=0) 281 | mag = mag[np.newaxis, ...] 282 | 283 | return flow, mag 284 | 285 | 286 | def run(img, sobel_size=5, etf_iter=4, etf_size=7, 287 | fdog_iter=3, thresh=0.001, sigma_c=1.0, rho=0.997, 288 | sigma_m=3.0, tau=0.907): 289 | """ 290 | Running coherent line drawing on input image. 291 | Parameters: 292 | ---------- 293 | - img : ndarray 294 | Input image, with shape = (h, w, c). 295 | 296 | - sobel_size : int, default = 5 297 | Size of sobel filter, sobel filter will be used to compute 298 | gradient. 299 | 300 | - etf_iter : int, default = 4 301 | Iteration times of refining edge tangent flow. 302 | 303 | - etf_size : int, default = 7 304 | Size of etf filter. 305 | 306 | - fdog_iter : int, default = 3 307 | Iteration times of applying fdog on input image. 308 | 309 | - thresh : float, default = 0.001 310 | Threshold of guass filter's value, this is not an important 311 | parameter. 312 | 313 | - sigma_c : float, default = 1.0 314 | Standard variance of one gaussian filter of dog filter, 315 | another's standard variance will be set to 1.6 * sigma_c. 316 | 317 | - rho : float, default = 0.997 318 | Dog = gauss_c - rho * gauss_s. 319 | 320 | - sigma_m : float, default = 3.0 321 | Standard variance of gaussian filter. 322 | 323 | - tau : float, default=0.907 324 | Threshold of edge map. 325 | Returns: 326 | ------- 327 | - edge : ndarray 328 | Edge map of input image, data type is float32 and pixel's 329 | range is clipped to [0, 255]. 330 | """ 331 | # initialize edge tangent flow 332 | flow, mag = initialze_flow(img, sobel_size) 333 | 334 | # refine edge tangent flow 335 | for i in range(etf_iter): 336 | flow = refine_flow(flow, mag, ksize=etf_size) 337 | 338 | # do fdog 339 | for i in range(fdog_iter): 340 | edge = detect_edge(img, flow, thresh=thresh, 341 | sigma_c=sigma_c, rho=rho, sigma_m=sigma_m, tau=tau) 342 | img[edge == 0] = 0 343 | img = cv.GaussianBlur(img, ksize=(3, 3), sigmaX=0, sigmaY=0) 344 | 345 | return detect_edge(img, flow, thresh=thresh, 346 | sigma_c=sigma_c, rho=rho, sigma_m=sigma_m, tau=tau) 347 | -------------------------------------------------------------------------------- /utils/__pycache__/Canny.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mq-yuan/EdgeDetection-for-ImageProcressing/8461efa5eba9cdd58a1fd8a571b392bd2f06b8a1/utils/__pycache__/Canny.cpython-38.pyc -------------------------------------------------------------------------------- /utils/__pycache__/Dog.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mq-yuan/EdgeDetection-for-ImageProcressing/8461efa5eba9cdd58a1fd8a571b392bd2f06b8a1/utils/__pycache__/Dog.cpython-38.pyc -------------------------------------------------------------------------------- /utils/__pycache__/FDoG.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mq-yuan/EdgeDetection-for-ImageProcressing/8461efa5eba9cdd58a1fd8a571b392bd2f06b8a1/utils/__pycache__/FDoG.cpython-38.pyc -------------------------------------------------------------------------------- /utils/img_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mq-yuan/EdgeDetection-for-ImageProcressing/8461efa5eba9cdd58a1fd8a571b392bd2f06b8a1/utils/img_6.png --------------------------------------------------------------------------------