├── README.md ├── import_test.py ├── import_test.ipynb ├── crop_batch_photo.ipynb ├── basic_function.py ├── caijian.ipynb ├── mat.py ├── kuandujisuan.ipynb ├── xuanzhuan.ipynb ├── gujiatiqu.ipynb ├── try.ipynb └── test.ipynb /README.md: -------------------------------------------------------------------------------- 1 | # liefengceliang 2 | fpn网络提取裂缝,MAT算法提取裂缝骨架,批量化自动识别裂缝最大宽度和统计宽度 3 | -------------------------------------------------------------------------------- /import_test.py: -------------------------------------------------------------------------------- 1 | def Print(): 2 | print('__name__') 3 | 4 | print("this is one") 5 | if __name__ == '__main__': 6 | print('this is two') 7 | return -------------------------------------------------------------------------------- /import_test.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": {}, 7 | "outputs": [ 8 | { 9 | "name": "stdout", 10 | "output_type": "stream", 11 | "text": [ 12 | "this is one\n", 13 | "this is two\n" 14 | ] 15 | } 16 | ], 17 | "source": [ 18 | "print(\"this is one\")\n", 19 | "if __name__ == '__main__':\n", 20 | " print('this is two')" 21 | ] 22 | } 23 | ], 24 | "metadata": { 25 | "kernelspec": { 26 | "display_name": "Python [conda env:pytorch2]", 27 | "language": "python", 28 | "name": "conda-env-pytorch2-py" 29 | }, 30 | "language_info": { 31 | "codemirror_mode": { 32 | "name": "ipython", 33 | "version": 3 34 | }, 35 | "file_extension": ".py", 36 | "mimetype": "text/x-python", 37 | "name": "python", 38 | "nbconvert_exporter": "python", 39 | "pygments_lexer": "ipython3", 40 | "version": "3.6.2" 41 | } 42 | }, 43 | "nbformat": 4, 44 | "nbformat_minor": 2 45 | } 46 | -------------------------------------------------------------------------------- /crop_batch_photo.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "from PIL import Image" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": 4, 17 | "metadata": {}, 18 | "outputs": [ 19 | { 20 | "name": "stdout", 21 | "output_type": "stream", 22 | "text": [ 23 | "(934, 499)\n", 24 | "(635, 424)\n", 25 | "(865, 454)\n", 26 | "(728, 489)\n", 27 | "(846, 518)\n" 28 | ] 29 | } 30 | ], 31 | "source": [ 32 | "#切割成指定大小,且jpg,png随意换\n", 33 | "for i in range(1,6):\n", 34 | " img = Image.open(\"C:/Users/PC/Desktop/research/lijun/test2/image/\"+str(i)+\".png\")\n", 35 | " print(img.size)\n", 36 | " cropped = img.crop((0, 0, 320, 320)) # (left, upper, right, lower)\n", 37 | " cropped.save(\"C:/Users/PC/Desktop/research/lijun/test2/\"+str(i)+\".png\")" 38 | ] 39 | }, 40 | { 41 | "cell_type": "code", 42 | "execution_count": null, 43 | "metadata": { 44 | "collapsed": true 45 | }, 46 | "outputs": [], 47 | "source": [ 48 | "#jpg转为png\n", 49 | "for i in range(1,30):\n", 50 | " img = Image.open(\"C:/Users/PC/Desktop/research/unet-crack/data/membrane/test2/\"+str(i)+\".png\")\n", 51 | " print(img.size)\n", 52 | " cropped = img.crop((0, 0, 256, 256)) # (left, upper, right, lower)\n", 53 | " cropped.save(\"C:/Users/PC/Desktop/research/unet-crack/data/membrane/test3/\"+str(i)+\".png\")" 54 | ] 55 | } 56 | ], 57 | "metadata": { 58 | "kernelspec": { 59 | "display_name": "Python [conda env:pytorch2]", 60 | "language": "python", 61 | "name": "conda-env-pytorch2-py" 62 | }, 63 | "language_info": { 64 | "codemirror_mode": { 65 | "name": "ipython", 66 | "version": 3 67 | }, 68 | "file_extension": ".py", 69 | "mimetype": "text/x-python", 70 | "name": "python", 71 | "nbconvert_exporter": "python", 72 | "pygments_lexer": "ipython3", 73 | "version": "3.6.2" 74 | } 75 | }, 76 | "nbformat": 4, 77 | "nbformat_minor": 4 78 | } 79 | -------------------------------------------------------------------------------- /basic_function.py: -------------------------------------------------------------------------------- 1 | """ 2 | @leofansq 3 | https://github.com/leofansq 4 | """ 5 | import cv2 6 | import numpy as np 7 | 8 | def erode(img): 9 | """ 10 | 使用3*3矩形结构子 腐蚀操作 11 | Parameter: 12 | img: 待腐蚀图像 13 | Return: 14 | img_result: 腐蚀结果图像 15 | """ 16 | # 初始化图像平移矩阵 17 | m_1 = np.array([[1,0,-1],[0,1,-1]], dtype=np.float32) 18 | m_2 = np.array([[1,0,0],[0,1,-1]], dtype=np.float32) 19 | m_3 = np.array([[1,0,1],[0,1,-1]], dtype=np.float32) 20 | m_4 = np.array([[1,0,-1],[0,1,0]], dtype=np.float32) 21 | m_5 = np.array([[1,0,1],[0,1,0]], dtype=np.float32) 22 | m_6 = np.array([[1,0,-1],[0,1,1]], dtype=np.float32) 23 | m_7 = np.array([[1,0,0],[0,1,1]], dtype=np.float32) 24 | m_8 = np.array([[1,0,1],[0,1,1]], dtype=np.float32) 25 | M = [m_1, m_2, m_3, m_4, m_5, m_6, m_7, m_8] 26 | 27 | # 9个平移后的图像取交集得到腐蚀结果 28 | img_result = img.copy() 29 | for i in M: 30 | img_shift = cv2.warpAffine(img, i, (img.shape[1],img.shape[0])) 31 | img_result = cv2.bitwise_and(img_result, img_shift) 32 | 33 | return img_result 34 | 35 | def dilate(img): 36 | """ 37 | 使用3*3矩形结构子 膨胀操作 38 | Parameter: 39 | img: 待膨胀图像 40 | Return: 41 | img_result: 膨胀结果图像 42 | """ 43 | # 初始化图像平移矩阵 44 | m_1 = np.array([[1,0,-1],[0,1,-1]], dtype=np.float32) 45 | m_2 = np.array([[1,0,0],[0,1,-1]], dtype=np.float32) 46 | m_3 = np.array([[1,0,1],[0,1,-1]], dtype=np.float32) 47 | m_4 = np.array([[1,0,-1],[0,1,0]], dtype=np.float32) 48 | m_5 = np.array([[1,0,1],[0,1,0]], dtype=np.float32) 49 | m_6 = np.array([[1,0,-1],[0,1,1]], dtype=np.float32) 50 | m_7 = np.array([[1,0,0],[0,1,1]], dtype=np.float32) 51 | m_8 = np.array([[1,0,1],[0,1,1]], dtype=np.float32) 52 | M = [m_1, m_2, m_3, m_4, m_5, m_6, m_7, m_8] 53 | 54 | # 9个平移后的图像取并集得到腐蚀结果 55 | img_result = img.copy() 56 | for i in M: 57 | img_shift = cv2.warpAffine(img, i, (img.shape[1],img.shape[0])) 58 | img_result = cv2.bitwise_or(img_result, img_shift) 59 | 60 | return img_result 61 | 62 | def open_morph(img): 63 | """ 64 | 开运算 65 | Parameter: 66 | img: 待进行开运算的图像 67 | Return: 68 | img_result: 开运算结果图像 69 | """ 70 | # 先腐蚀, 再膨胀 71 | img_result = erode(img) 72 | img_result = dilate(img_result) 73 | 74 | return img_result 75 | 76 | def show_img(name, img): 77 | """ 78 | Show the image 79 | Parameters: 80 | name: name of window 81 | img: image 82 | """ 83 | cv2.namedWindow(name, 0) 84 | cv2.imshow(name, img) 85 | 86 | # if __name__ == "__main__": 87 | # img = np.array([[0,0,0,0,0],[0,255,255,255,0],[255,255,255,255,255],[0,255,255,255,0],[0,0,0,0,0]], dtype=np.uint8) 88 | # show_img("origin", img) 89 | # img_erode = erode(img) 90 | # show_img("erode", img_erode) 91 | # img_dilate = dilate(img) 92 | # show_img("dilate", img_dilate) 93 | # img_open = open_morph(img) 94 | # show_img("open", img_open) 95 | 96 | # cv2.waitKey() 97 | # cv2.destroyAllWindows() -------------------------------------------------------------------------------- /caijian.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "#python3,去除骨架的毛刺\n", 12 | "import os\n", 13 | "import cv2\n", 14 | "import numpy as np\n", 15 | "import matplotlib.pyplot as plt\n", 16 | "import albumentations as albu\n", 17 | "from basic_function import dilate" 18 | ] 19 | }, 20 | { 21 | "cell_type": "code", 22 | "execution_count": null, 23 | "metadata": { 24 | "collapsed": true 25 | }, 26 | "outputs": [], 27 | "source": [ 28 | "def thinning(img, K):\n", 29 | " \"\"\"\n", 30 | " 细化\n", 31 | " Parameters:\n", 32 | " img: 待细化图像\n", 33 | " K: 结构子序列\n", 34 | " Return:\n", 35 | " 细化后结果图像\n", 36 | " \"\"\"\n", 37 | " # 归一\n", 38 | " img_result = img/255\n", 39 | " # 利用结构子序列重复3次细化\n", 40 | " for i in range(3):\n", 41 | " for i in K:\n", 42 | " img_temp = np.where(cv2.filter2D(img_result.copy(),-1,i,borderType=0)==3, 1, 0)\n", 43 | " img_result = img_result - img_temp\n", 44 | " \n", 45 | " img_result *= 255\n", 46 | " return img_result.astype(np.uint8)\n", 47 | "\n", 48 | "def find_end(img, K):\n", 49 | " \"\"\"\n", 50 | " 找到端节点\n", 51 | " Parameters:\n", 52 | " img: 输入图像\n", 53 | " K: 结构子序列\n", 54 | " Return:\n", 55 | " 只有端节点为前景的图像\n", 56 | " \"\"\"\n", 57 | " # 像素归一化\n", 58 | " img_ones = img/255\n", 59 | " img_result = np.zeros_like(img, dtype=np.uint8)\n", 60 | "\n", 61 | " # 利用结构子序列寻找端点\n", 62 | " for i in K:\n", 63 | " img_temp = np.where(cv2.filter2D(img_ones.copy(),-1,i,borderType=0)==3, 1, 0)\n", 64 | " img_result = img_result + img_temp\n", 65 | " \n", 66 | " img_result *= 255\n", 67 | " return img_result.astype(np.uint8)\n", 68 | "\n", 69 | "def tailor(img):\n", 70 | " \"\"\"\n", 71 | " 裁剪\n", 72 | " Parameters:\n", 73 | " img: 待裁剪图像\n", 74 | " Return:\n", 75 | " 裁剪结果图像\n", 76 | " \"\"\"\n", 77 | " # 生成8个结构子\n", 78 | " k_1 = np.array([[0,4,4],[1,2,4],[0,4,4]], dtype=np.uint8)\n", 79 | " k_2 = np.array([[0,1,0],[4,2,4],[4,4,4]], dtype=np.uint8)\n", 80 | " k_3 = np.array([[4,4,0],[4,1,2],[4,4,0]], dtype=np.uint8)\n", 81 | " k_4 = np.array([[4,4,4],[4,1,4],[0,2,0]], dtype=np.uint8)\n", 82 | " k_5 = np.array([[1,4,4],[4,2,4],[4,4,4]], dtype=np.uint8)\n", 83 | " k_6 = np.array([[4,4,1],[4,2,4],[4,4,4]], dtype=np.uint8)\n", 84 | " k_7 = np.array([[4,4,4],[4,1,4],[4,4,2]], dtype=np.uint8)\n", 85 | " k_8 = np.array([[4,4,4],[4,1,4],[2,4,4]], dtype=np.uint8) \n", 86 | "\n", 87 | " K = [k_1, k_2, k_3, k_4, k_5, k_6, k_7, k_8]\n", 88 | "\n", 89 | " # 细化(去除3个像素组成的分支)\n", 90 | " img_thin = thinning(img, K)\n", 91 | " # 找端点\n", 92 | " img_end = find_end(img_thin, K)\n", 93 | " # 膨胀运算,捡回误伤元素\n", 94 | " img_dilate = img_end\n", 95 | " for _ in range(3):\n", 96 | " img_dilate = dilate(img_dilate)\n", 97 | " img_dilate = cv2.bitwise_and(img_dilate, img)\n", 98 | " # 获得裁剪结果\n", 99 | " img_result = cv2.bitwise_or(img_dilate, img_thin)\n", 100 | "\n", 101 | " return img_result\n", 102 | "\n", 103 | "\n", 104 | "if __name__ == \"__main__\":\n", 105 | " img = cv2.imread(\"morph_thin.png\", 0)\n", 106 | " img_result = tailor(img)\n", 107 | " cv2.imwrite(\"tailor.png\", img_result)\n", 108 | "© 2021 GitHub, Inc.\n", 109 | "Terms\n", 110 | "Privacy\n", 111 | "Security\n", 112 | "Status\n", 113 | "Docs\n", 114 | "Contact GitHub\n", 115 | "Pricing\n", 116 | "API\n", 117 | "Training\n", 118 | "Blog\n", 119 | "About\n", 120 | "Loading complete" 121 | ] 122 | } 123 | ], 124 | "metadata": { 125 | "kernelspec": { 126 | "display_name": "Python [conda env:pytorch2]", 127 | "language": "python", 128 | "name": "conda-env-pytorch2-py" 129 | }, 130 | "language_info": { 131 | "codemirror_mode": { 132 | "name": "ipython", 133 | "version": 3 134 | }, 135 | "file_extension": ".py", 136 | "mimetype": "text/x-python", 137 | "name": "python", 138 | "nbconvert_exporter": "python", 139 | "pygments_lexer": "ipython3", 140 | "version": "3.6.2" 141 | } 142 | }, 143 | "nbformat": 4, 144 | "nbformat_minor": 2 145 | } 146 | -------------------------------------------------------------------------------- /mat.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # cython: language_level=3 4 | """ 5 | @Time : 2020/4/28 11:13 6 | @Author : Zhang Qi 7 | @Email : zhangqi@onlinesign.com.cn 8 | @File : mat.py 9 | @Title : MAT算法 10 | @Description : 11 | MAT算法用于给定一个字的图片,通过MAT算法返回这个字对应的骨架图片 12 | """ 13 | import numpy as np 14 | from functools import reduce 15 | 16 | 17 | # ================================================================= 18 | # MAT算法提取骨架 19 | # ================================================================= 20 | 21 | 22 | def __mat_process_first(around_area: np.ndarray) -> bool: 23 | """MAT算法步骤1 24 | 25 | 对于相邻像素区域: 26 | [ 27 | [p9,p2,p3], 28 | [p8,p1,p4], 29 | [p7,p6,p5] 30 | ] 31 | 包括以下几个部分: 32 | a. 2 <=非零像素个数 <= 6 33 | b. 顺时针跳数 = 1 34 | c. p2 * p4 * p6 = 0 35 | d. p4 * p6 * p8 = 0 36 | 37 | :param around_area: numpy.array, 一个像素的相邻像素,为3*3 38 | :return: bool,是否满足以上所有条件 39 | """ 40 | result_list = list() # 保存所有步骤是否符合条件 41 | """步骤a""" 42 | near_one_count = __near_pix_equal_one_count(around_area) 43 | result_list.append(2 <= near_one_count <= 6) 44 | """步骤b""" 45 | result_list.append(__binary_transform_count(around_area) == 1) 46 | """步骤c""" 47 | pix_2 = around_area[0][1] 48 | pix_4 = around_area[1][2] 49 | pix_6 = around_area[2][1] 50 | result_list.append(pix_2 * pix_4 * pix_6 == 0) 51 | """步骤d""" 52 | pix_8 = around_area[1][0] 53 | result_list.append(pix_4 * pix_6 * pix_8 == 0) 54 | 55 | return bool(reduce(lambda x, y: x and y, result_list)) 56 | 57 | 58 | def __mat_process_second(around_area: np.ndarray) -> bool: 59 | """MAT算法步骤2 60 | 对于相邻像素区域: 61 | [ 62 | [p9,p2,p3], 63 | [p8,p1,p4], 64 | [p7,p6,p5] 65 | ] 66 | 包括以下几个部分: 67 | a. 2 <=非零像素个数 <= 6 68 | b. 顺时针跳数 = 1 69 | c. p2 * p4 * p8 = 0 70 | d. p2 * p6 * p8 = 0 71 | :param around_area: numpy.array, 周围的区域 72 | :return: bool,是否全部子条件 73 | """ 74 | result_list = list() # 保存所有步骤是否符合条件 75 | """步骤a""" 76 | near_one_count = __near_pix_equal_one_count(around_area) 77 | result_list.append(2 <= near_one_count <= 6) 78 | """步骤b""" 79 | result_list.append(__binary_transform_count(around_area) == 1) 80 | """步骤c""" 81 | pix_2 = around_area[0][1] 82 | pix_4 = around_area[1][2] 83 | pix_8 = around_area[1][0] 84 | pix_6 = around_area[2][1] 85 | result_list.append(pix_2 * pix_4 * pix_8 == 0) 86 | """步骤d""" 87 | result_list.append(pix_2 * pix_6 * pix_8 == 0) 88 | 89 | return bool(reduce(lambda x, y: x and y, result_list)) 90 | 91 | 92 | def __near_pix_equal_one_count(around_area: np.ndarray) -> int or np.int: 93 | """计算相邻像素中为1的个数(不包括中间点) 94 | 95 | 即,对于相邻像素区域: 96 | [ 97 | [p9,p2,p3], 98 | [p8,p1,p4], 99 | [p7,p6,p5] 100 | ] 101 | 统计出p1之外所有的1的个数 102 | :param around_area: numpy.array, 一个像素的相邻像素,为3*3 103 | :return int,像素为1的个数 104 | """ 105 | temp_around_area = np.copy(around_area) 106 | temp_around_area[1][1] = 0 107 | return int(np.sum(temp_around_area, dtype=np.int)) 108 | 109 | 110 | def __binary_transform_count(around_area: np.ndarray) -> int or np.int: 111 | """给定一个3*3的二进制图片,获取其顺时针的跳数(从0到1) 112 | 113 | 即,对于相邻像素区域: 114 | [ 115 | [p9,p2,p3], 116 | [p8,p1,p4], 117 | [p7,p6,p5] 118 | ] 119 | 以p9,p2,p3,p4,p5,p6,p7,p8的顺序访问,如果是0到1,则为一跳 120 | :param around_area: numpy.array, 一个像素的相邻像素,为3*3 121 | :return int, 顺时针跳数 122 | """ 123 | def __next_index(current_coor: (int, int)) -> (int, int): 124 | """给定当前位置,返回下一个位置 125 | 126 | :param current_coor: (int,int),当前位置 127 | :return: (int,int), 下一个位置 128 | """ 129 | '''四个方向的下一个位置''' 130 | right_next = (current_coor[0], current_coor[1] + 1) 131 | down_next = (current_coor[0] + 1, current_coor[1]) 132 | left_next = (current_coor[0], current_coor[1] - 1) 133 | up_next = (current_coor[0] - 1, current_coor[1]) 134 | 135 | """按照指定的规则寻找,不报错则表示正确的方向""" 136 | next_coordinate_list = [right_next, down_next, left_next, up_next] 137 | for i, next_coordinate in enumerate(next_coordinate_list): 138 | try: 139 | around_area[next_coordinate] 140 | except IndexError: 141 | continue 142 | else: 143 | '''如果该点已经走过''' 144 | if is_walked[next_coordinate[0], next_coordinate[1]]: 145 | continue 146 | else: 147 | is_walked[next_coordinate[0], next_coordinate[1]] = True 148 | return next_coordinate 149 | 150 | is_walked = np.full_like(around_area, False) # 用于标识该点是否已经走过 151 | is_walked[1][1] = True 152 | transform_count = 0 # 用于记录跳数 153 | """循环对比""" 154 | last_pix = around_area[0][0] # 上一个的值 155 | current_coordinate = (0, 1) 156 | while current_coordinate != (0, 0): 157 | current_pix = around_area[current_coordinate[0], current_coordinate[1]] 158 | if last_pix == 0 and current_pix == 1: 159 | transform_count += 1 160 | 161 | last_pix = current_pix 162 | current_coordinate = __next_index(current_coordinate) 163 | 164 | '''当循环到第一个点时再对比一次''' 165 | current_pix = around_area[current_coordinate[0], current_coordinate[0]] 166 | if last_pix == 0 and current_pix == 1: 167 | transform_count += 1 168 | 169 | return transform_count 170 | 171 | 172 | def __remove_pix_by_coordination(img: np.ndarray, points: list): 173 | """给定坐标的list,删除图像上的点(实际就是标记为0) 174 | 175 | :param img: numpy.array,图像 176 | :param points: List[(int,int)] 177 | """ 178 | for single_coordination in points: 179 | i_row, i_col = single_coordination 180 | img[i_row][i_col] = 0 181 | 182 | 183 | def __get_remove_points(img: np.ndarray, func) -> [(int, int)]: 184 | """给定图像以及,删除点的规则,返回要删除的点 185 | 186 | :param img: numpy.array, 原图像 187 | :param func: function, 规则,也就是一个函数 188 | :return: List[(int,int)],坐标的list 189 | """ 190 | remove_points_list = list() 191 | temp_img = img 192 | img_iter = np.nditer(temp_img, flags=["multi_index"]) 193 | while not img_iter.finished: 194 | current_pix = img_iter[0] 195 | i_row, i_col = img_iter.multi_index 196 | img_iter.iternext() 197 | '''如果是背景点则直接跳过''' 198 | if current_pix != 1: 199 | continue 200 | 201 | """如果是前景点""" 202 | around_area = temp_img[i_row - 1:i_row + 2, i_col - 1:i_col + 2] 203 | if func(around_area): 204 | remove_points_list.append((i_row, i_col)) 205 | 206 | img_iter.iternext() 207 | return remove_points_list 208 | 209 | 210 | def get_img_skeleton_by_mat(img: np.ndarray) -> np.ndarray: 211 | """根据字体的图像得到字的骨架 212 | 213 | :param img, numpy.array, 原图片 214 | :raise ValueError 215 | - 图片不为单通道 216 | - 图片并未归一化 217 | - 图片并未标准化 218 | :return: numpy.array, 骨架图 219 | """ 220 | '''检验图片是否是单通道''' 221 | if len(img.shape) != 2: 222 | raise ValueError("该图片不是单通道") 223 | """检验标准化""" 224 | if img.max() > 1: 225 | raise ValueError("该图片并未标准化") 226 | """检验二值化""" 227 | if (np.unique(img.flatten()) != (0, 1)).all(): 228 | raise ValueError("该函数并未二值化") 229 | 230 | temp_img = img.copy() 231 | """遍历每一个像素点""" 232 | is_remove_flag = True # 表示是否继续删除的标志 233 | i_round = 1 # 记录迭代的轮数 234 | while is_remove_flag: 235 | is_remove_flag = False 236 | print("正在执行MAT算法的第{}轮".format(i_round)) 237 | """执行步骤1""" 238 | remove_points = __get_remove_points(temp_img, __mat_process_first) 239 | if len(remove_points) != 0: 240 | is_remove_flag = True 241 | __remove_pix_by_coordination(temp_img, remove_points) 242 | 243 | """执行步骤2""" 244 | remove_points = __get_remove_points(temp_img, __mat_process_second) 245 | if len(remove_points) != 0: 246 | is_remove_flag = True 247 | __remove_pix_by_coordination(temp_img, remove_points) 248 | 249 | i_round += 1 250 | 251 | return temp_img 252 | -------------------------------------------------------------------------------- /kuandujisuan.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "#import segmentation_models_pytorch as smp\n", 12 | "import os\n", 13 | "import numpy as np\n", 14 | "import cv2\n", 15 | "import matplotlib.pyplot as plt\n", 16 | "import albumentations as albu\n", 17 | "#import torch\n", 18 | "import numpy as np\n", 19 | "#from torch.utils.data import DataLoader\n", 20 | "#from torch.utils.data import Dataset as BaseDataset\n", 21 | "os.environ['CUDA_VISIBLE_DEVICES'] = '0'" 22 | ] 23 | }, 24 | { 25 | "cell_type": "code", 26 | "execution_count": 2, 27 | "metadata": { 28 | "collapsed": true 29 | }, 30 | "outputs": [], 31 | "source": [ 32 | "#将图片路径写成列表,为后面cv2读入方便\n", 33 | "images_dir = 'liefeng'\n", 34 | "ids=sorted(os.listdir(images_dir))\n", 35 | "images_fps=[os.path.join(images_dir, image_id) for image_id in ids]" 36 | ] 37 | }, 38 | { 39 | "cell_type": "code", 40 | "execution_count": 3, 41 | "metadata": { 42 | "collapsed": true 43 | }, 44 | "outputs": [], 45 | "source": [ 46 | "#批量处理,文件夹内20张照片读成np.array存入3维array‘image’,第一维代表第几张照片\n", 47 | "j=0\n", 48 | "image = np.zeros(shape=(len(images_fps),320,320))\n", 49 | "for i in images_fps:\n", 50 | " image1 = cv2.imread(i,1)\n", 51 | " image1 = cv2.cvtColor(image1, cv2.COLOR_BGR2RGB)\n", 52 | " #像素值变成0-1\n", 53 | " image2=image1[:,:,1]\n", 54 | " image2=image2-image2.min()\n", 55 | " image2=image2/image2.max()\n", 56 | " #照片周围变成空白像素,否则mat算法会报错\n", 57 | " image2[0,:]=0\n", 58 | " image2[image2.shape[0]-1,:]=0\n", 59 | " image2[:,0]=0\n", 60 | " image2[:,image2.shape[1]-1]=0\n", 61 | " image2=np.reshape(image2,(320,320))\n", 62 | " image[j,:,:]=image2\n", 63 | " j=j+1" 64 | ] 65 | }, 66 | { 67 | "cell_type": "code", 68 | "execution_count": 5, 69 | "metadata": { 70 | "collapsed": true 71 | }, 72 | "outputs": [], 73 | "source": [ 74 | "#用于检查是否读入,cv2显式照片\n", 75 | "cv2.namedWindow(\"Image\",0)\n", 76 | "cv2.imshow('Image',image[1,:,:])\n", 77 | "cv2.waitKey()\n", 78 | "cv2.destroyAllWindows()" 79 | ] 80 | }, 81 | { 82 | "cell_type": "code", 83 | "execution_count": 6, 84 | "metadata": { 85 | "collapsed": true 86 | }, 87 | "outputs": [], 88 | "source": [ 89 | "#从复合图分离\n", 90 | "'''\n", 91 | "之前的复合图像\n", 92 | "skeleton_img=skeleton_img*200#matplot为0-255绘图,0黑,255白。\n", 93 | "skeleton_img_liefeng=skeleton_img+image*55\n", 94 | "for n in range (0,19):\n", 95 | " #matplotlib.image.imsave(\"liefeng/%04.d.png\"%(n+1),skeleton_img[n,:,:])\n", 96 | " cv2.imwrite(\"liefeng/%04.d.png\"%(n+1),skeleton_img_liefeng[n,:,:])\n", 97 | "'''\n", 98 | "image_liefeng=np.zeros_like(image)\n", 99 | "image_gujia=np.zeros_like(image)\n", 100 | "image_gujia[image > 0.99]=1\n", 101 | "image_liefeng[image >0.1]=1" 102 | ] 103 | }, 104 | { 105 | "cell_type": "code", 106 | "execution_count": 7, 107 | "metadata": { 108 | "collapsed": true 109 | }, 110 | "outputs": [], 111 | "source": [ 112 | "Image_gujia=image_gujia*255#放大到0-255用于保存照片\n", 113 | "Image_liefeng=image_liefeng*255#放大的到0-255用于保存照片" 114 | ] 115 | }, 116 | { 117 | "cell_type": "code", 118 | "execution_count": 6, 119 | "metadata": { 120 | "collapsed": true 121 | }, 122 | "outputs": [], 123 | "source": [ 124 | "#用于检查是否读入,cv2显式照片,0=黑,1=白\n", 125 | "cv2.namedWindow(\"Image\",0)\n", 126 | "cv2.imshow('Image',image_liefeng[1,:,:])\n", 127 | "cv2.waitKey()\n", 128 | "cv2.destroyAllWindows()" 129 | ] 130 | }, 131 | { 132 | "cell_type": "code", 133 | "execution_count": 56, 134 | "metadata": { 135 | "collapsed": true 136 | }, 137 | "outputs": [], 138 | "source": [ 139 | "#opencv保存成照片(0-255,因此需要先放大255倍),放在liefeng文件夹\n", 140 | "for n in range (0,19):\n", 141 | " #matplotlib.image.imsave(\"liefeng/gujia%04.d.png\"%(n+1),Image_gujia[n,:,:])\n", 142 | " cv2.imwrite(\"gujia/%04.d.png\"%(n+1),Image_gujia[n,:,:])\n", 143 | " cv2.imwrite(\"liefeng2/%04.d.png\"%(n+1),Image_liefeng[n,:,:])" 144 | ] 145 | }, 146 | { 147 | "cell_type": "code", 148 | "execution_count": 9, 149 | "metadata": { 150 | "collapsed": true 151 | }, 152 | "outputs": [], 153 | "source": [ 154 | "def get_gujia_point(image):\n", 155 | " \"接受骨架灰度照片(0-1),返回2维ndarray,记录所有骨架像素点位置\"\n", 156 | " gujia_P=np.nonzero(image)\n", 157 | " gujia_p=np.array(gujia_P)\n", 158 | " return gujia_p\n", 159 | "gujia_p4=get_gujia_point(image_gujia[1,:,:])" 160 | ] 161 | }, 162 | { 163 | "cell_type": "code", 164 | "execution_count": 10, 165 | "metadata": { 166 | "collapsed": true 167 | }, 168 | "outputs": [], 169 | "source": [ 170 | "#返回一张照片的所有骨架像素点位置\n", 171 | "def get_gujia_point(image):\n", 172 | " \"接受骨架灰度照片(0-1),返回2维ndarray,记录所有骨架像素点位置\"\n", 173 | " gujia_P=np.nonzero(image)\n", 174 | " gujia_p=np.array(gujia_P)\n", 175 | " return gujia_p\n", 176 | "gujia_p4=get_gujia_point\n", 177 | "\n", 178 | "#返回所有框选宽度\n", 179 | "def get_w(image_liefeng,image_gujia,point,w,h):\n", 180 | " \"输入image裂缝照片,point骨架点(2dimension,第一维代表纵坐标,第二位横坐标),w框选半宽,h框选半高,返回所有框选出照片的所有宽度,存放在ndarray'list中'\"\n", 181 | " n=point.shape[1]\n", 182 | " list=[]\n", 183 | " for i in range(0,n-1):\n", 184 | " #防止-h,-w后下标越界;上界可以越没关系\n", 185 | " if point[0,i]-h>=0 and point[1,i]-w>=0:\n", 186 | " img_for_w=image_liefeng[point[0,i]-h:point[0,i]+h,point[1,i]-w:point[1,i]+w]\n", 187 | " gj_for_w=image_gujia[point[0,i]-h:point[0,i]+h,point[1,i]-w:point[1,i]+w]\n", 188 | " elif point[0,i]-h>=0 and point[1,i]-w<0:\n", 189 | " img_for_w=image_liefeng[point[0,i]-h:point[0,i]+h,0:point[1,i]+w]\n", 190 | " gj_for_w=image_gujia[point[0,i]-h:point[0,i]+h,0:point[1,i]+w]\n", 191 | " elif point[0,i]-h<0 and point[1,i]-w>=0:\n", 192 | " img_for_w=image_liefeng[0:point[0,i]+h,point[1,i]-w:point[1,i]+w]\n", 193 | " gj_for_w=image_gujia[0:point[0,i]+h,point[1,i]-w:point[1,i]+w]\n", 194 | " else:\n", 195 | " img_for_w=image_liefeng[0:point[0,i]+h,0:point[1,i]+w]\n", 196 | " gj_for_w=image_gujia[0:point[0,i]+h,0:point[1,i]+w]\n", 197 | " width=calculate_width(img_for_w,gj_for_w)\n", 198 | " list.append(width)\n", 199 | " return list\n", 200 | "#给出骨架和裂缝图片,统计点数,计算框选宽度\n", 201 | "def calculate_width(image_for_w,gujia_for_w):\n", 202 | " \"img_for_w框选的裂缝图,gj_for_w框选的骨架图,最后返回计算的平均宽度\"\n", 203 | " area=np.count_nonzero(image_for_w)\n", 204 | " length=np.count_nonzero(gujia_for_w)\n", 205 | " width=area/(length)\n", 206 | " return width\n", 207 | "\n", 208 | "def get_width(image_liefeng,image_gujia,w,h):\n", 209 | " gujia_p=get_gujia_point(image_gujia)\n", 210 | " width=get_w(image_liefeng,image_gujia,gujia_p,w,h)\n", 211 | " return width\n", 212 | "#width=get_width(image_liefeng[1,:,:],image_gujia[1,:,:],10,10)\n", 213 | "#width[400:450]\n", 214 | "#img_for_w=get_img_for_w(image_liefeng[3,:,:],gujia_p4,w,h) " 215 | ] 216 | }, 217 | { 218 | "cell_type": "code", 219 | "execution_count": 11, 220 | "metadata": { 221 | "collapsed": true 222 | }, 223 | "outputs": [], 224 | "source": [ 225 | "w=10\n", 226 | "h=10\n", 227 | "width_all=[]\n", 228 | "for i in range(19):\n", 229 | " width=get_width(image_liefeng[i,:,:],image_gujia[i,:,:],30,30)\n", 230 | " width_sort=sorted(width,reverse=True)\n", 231 | " width_sort=width_sort[0:20]\n", 232 | " width_all.append(width_sort)" 233 | ] 234 | }, 235 | { 236 | "cell_type": "code", 237 | "execution_count": 18, 238 | "metadata": {}, 239 | "outputs": [ 240 | { 241 | "data": { 242 | "text/plain": [ 243 | "[24.974358974358974,\n", 244 | " 24.833333333333332,\n", 245 | " 24.833333333333332,\n", 246 | " 24.79746835443038,\n", 247 | " 24.705128205128204,\n", 248 | " 24.705128205128204,\n", 249 | " 24.442307692307693,\n", 250 | " 24.345454545454544,\n", 251 | " 24.240506329113924,\n", 252 | " 24.20689655172414,\n", 253 | " 24.088607594936708,\n", 254 | " 24.088607594936708,\n", 255 | " 24.0327868852459,\n", 256 | " 24.024390243902438,\n", 257 | " 24.024390243902438,\n", 258 | " 23.924050632911392,\n", 259 | " 23.84375,\n", 260 | " 23.759493670886076,\n", 261 | " 23.759493670886076,\n", 262 | " 23.73076923076923]" 263 | ] 264 | }, 265 | "execution_count": 18, 266 | "metadata": {}, 267 | "output_type": "execute_result" 268 | } 269 | ], 270 | "source": [] 271 | }, 272 | { 273 | "cell_type": "code", 274 | "execution_count": 43, 275 | "metadata": {}, 276 | "outputs": [ 277 | { 278 | "name": "stdout", 279 | "output_type": "stream", 280 | "text": [ 281 | "[23.1875, 22.88235294117647, 22.266666666666666, 22.11111111111111, 21.357142857142858, 21.05263157894737, 20.46153846153846, 20.272727272727273, 20.25, 20.23076923076923, 20.214285714285715, 20.2, 20.1875, 20.176470588235293, 20.166666666666668, 20.157894736842106, 20.0, 20.0, 20.0, 20.0] \n", 282 | "\n", 283 | " [39.54545454545455, 39.523809523809526, 34.375, 34.31707317073171, 33.743589743589745, 33.38095238095238, 33.333333333333336, 33.333333333333336, 33.208333333333336, 33.125, 33.041666666666664, 32.86842105263158, 32.6530612244898, 32.6530612244898, 32.6530612244898, 32.6530612244898, 32.6530612244898, 32.63265306122449, 32.61224489795919, 32.59183673469388] \n", 284 | "\n", 285 | " [43.465753424657535, 43.361111111111114, 43.16216216216216, 43.082191780821915, 43.02777777777778, 42.0958904109589, 41.753246753246756, 41.16216216216216, 40.24, 39.78048780487805, 39.46341463414634, 39.328947368421055, 38.44155844155844, 38.03896103896104, 37.724137931034484, 37.166666666666664, 36.31645569620253, 36.285714285714285, 35.56382978723404, 35.5] \n", 286 | "\n", 287 | " [39.58095238095238, 38.862385321100916, 37.391304347826086, 37.243478260869566, 35.93388429752066, 34.976377952755904, 34.88095238095238, 34.53076923076923, 33.85820895522388, 33.231884057971016, 32.51748251748252, 32.41258741258741, 31.965986394557824, 31.450331125827816, 31.24025974025974, 31.162337662337663, 30.955414012738853, 30.68125, 30.47239263803681, 30.411042944785276]\n" 288 | ] 289 | } 290 | ], 291 | "source": [ 292 | "width_sort=sorted(width,reverse=True)\n", 293 | "width20_sort=sorted(width20,reverse=True)\n", 294 | "width30_sort=sorted(width30,reverse=True)\n", 295 | "width40_sort=sorted(width40,reverse=True)\n", 296 | "print(width_sort[0:20],'\\n\\n',width20_sort[0:20],'\\n\\n',width30_sort[0:20],'\\n\\n',width40_sort[0:20])" 297 | ] 298 | }, 299 | { 300 | "cell_type": "code", 301 | "execution_count": 34, 302 | "metadata": {}, 303 | "outputs": [ 304 | { 305 | "name": "stdout", 306 | "output_type": "stream", 307 | "text": [ 308 | "a\n", 309 | "b\n" 310 | ] 311 | } 312 | ], 313 | "source": [ 314 | "#" 315 | ] 316 | }, 317 | { 318 | "cell_type": "code", 319 | "execution_count": 18, 320 | "metadata": {}, 321 | "outputs": [ 322 | { 323 | "ename": "NameError", 324 | "evalue": "name 'img_for_w' is not defined", 325 | "output_type": "error", 326 | "traceback": [ 327 | "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", 328 | "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", 329 | "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[0mcv2\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mnamedWindow\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Image\"\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[0mcv2\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mimshow\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'Image'\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mimg_for_w\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 3\u001b[0m \u001b[0mcv2\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mwaitKey\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[0mcv2\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdestroyAllWindows\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[1;31m#gj_for_w=get_img_for_w(image_gujia,gujia_p,w,h)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 330 | "\u001b[1;31mNameError\u001b[0m: name 'img_for_w' is not defined" 331 | ] 332 | } 333 | ], 334 | "source": [ 335 | "cv2.namedWindow(\"Image\",0)\n", 336 | "cv2.imshow('Image',img_for_w[1])\n", 337 | "cv2.waitKey()\n", 338 | "cv2.destroyAllWindows()\n", 339 | "#gj_for_w=get_img_for_w(image_gujia,gujia_p,w,h)" 340 | ] 341 | }, 342 | { 343 | "cell_type": "code", 344 | "execution_count": 159, 345 | "metadata": { 346 | "collapsed": true 347 | }, 348 | "outputs": [], 349 | "source": [ 350 | "cv2.namedWindow(\"Image\",0)\n", 351 | "cv2.imshow('Image',img_for_w[0])\n", 352 | "cv2.waitKey()\n", 353 | "cv2.destroyAllWindows()" 354 | ] 355 | }, 356 | { 357 | "cell_type": "code", 358 | "execution_count": 162, 359 | "metadata": {}, 360 | "outputs": [ 361 | { 362 | "data": { 363 | "text/plain": [ 364 | "(3,)" 365 | ] 366 | }, 367 | "execution_count": 162, 368 | "metadata": {}, 369 | "output_type": "execute_result" 370 | } 371 | ], 372 | "source": [ 373 | "a=np.array([1,1])\n", 374 | "b=np.array([[1,1],[1,1]])\n", 375 | "list=[a,b]\n", 376 | "list[1]\n", 377 | "a=np.append(a,1)\n", 378 | "a.shape" 379 | ] 380 | }, 381 | { 382 | "cell_type": "code", 383 | "execution_count": 140, 384 | "metadata": {}, 385 | "outputs": [ 386 | { 387 | "data": { 388 | "text/plain": [ 389 | "True" 390 | ] 391 | }, 392 | "execution_count": 140, 393 | "metadata": {}, 394 | "output_type": "execute_result" 395 | } 396 | ], 397 | "source": [ 398 | "img_for_w=img_for_w*255\n", 399 | "cv2.imwrite(\"kuandu/%04.d.png\"%(1),img_for_w)" 400 | ] 401 | }, 402 | { 403 | "cell_type": "code", 404 | "execution_count": 141, 405 | "metadata": {}, 406 | "outputs": [ 407 | { 408 | "name": "stdout", 409 | "output_type": "stream", 410 | "text": [ 411 | "117 28 4.178571428571429\n" 412 | ] 413 | } 414 | ], 415 | "source": [ 416 | "print(area,' ',length,' ',width)" 417 | ] 418 | }, 419 | { 420 | "cell_type": "code", 421 | "execution_count": null, 422 | "metadata": { 423 | "collapsed": true 424 | }, 425 | "outputs": [], 426 | "source": [ 427 | "(16,19)\n", 428 | "(19,23)" 429 | ] 430 | } 431 | ], 432 | "metadata": { 433 | "kernelspec": { 434 | "display_name": "Python [conda env:pytorch2]", 435 | "language": "python", 436 | "name": "conda-env-pytorch2-py" 437 | }, 438 | "language_info": { 439 | "codemirror_mode": { 440 | "name": "ipython", 441 | "version": 3 442 | }, 443 | "file_extension": ".py", 444 | "mimetype": "text/x-python", 445 | "name": "python", 446 | "nbconvert_exporter": "python", 447 | "pygments_lexer": "ipython3", 448 | "version": "3.6.2" 449 | } 450 | }, 451 | "nbformat": 4, 452 | "nbformat_minor": 2 453 | } 454 | -------------------------------------------------------------------------------- /xuanzhuan.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "from PIL import Image\n", 12 | "import os\n", 13 | "import numpy as np\n", 14 | "import cv2\n", 15 | "import matplotlib.pyplot as plt\n", 16 | "import albumentations as albu\n", 17 | "#import torch\n", 18 | "import numpy as np\n", 19 | "from math import *\n", 20 | "#from torch.utils.data import DataLoader\n", 21 | "#from torch.utils.data import Dataset as BaseDataset" 22 | ] 23 | }, 24 | { 25 | "cell_type": "code", 26 | "execution_count": 2, 27 | "metadata": { 28 | "collapsed": true 29 | }, 30 | "outputs": [], 31 | "source": [ 32 | "#将图片路径写成列表,为后面cv2读入方便\n", 33 | "images_dir = 'liefeng'\n", 34 | "ids=sorted(os.listdir(images_dir))\n", 35 | "images_fps=[os.path.join(images_dir, image_id) for image_id in ids]" 36 | ] 37 | }, 38 | { 39 | "cell_type": "code", 40 | "execution_count": 3, 41 | "metadata": { 42 | "collapsed": true 43 | }, 44 | "outputs": [], 45 | "source": [ 46 | "#批量处理,文件夹内20张照片读成np.array存入3维array‘image’,第一维代表第几张照片\n", 47 | "j=0\n", 48 | "image = np.zeros(shape=(len(images_fps),320,320))\n", 49 | "for i in images_fps:\n", 50 | " image1 = cv2.imread(i,1)\n", 51 | " pil_img = Image.fromarray(cv2.cvtColor(image1,cv2.COLOR_BGR2RGB))#opencv转为pil\n", 52 | " #image1 = cv2.cvtColor(image1, cv2.COLOR_BGR2RGB)\n", 53 | " #像素值变成0-1\n", 54 | " image2=image1[:,:,1]\n", 55 | " image2=image2-image2.min()\n", 56 | " image2=image2/image2.max()\n", 57 | " #照片周围变成空白像素,否则mat算法会报错\n", 58 | " image2[0,:]=0\n", 59 | " image2[image2.shape[0]-1,:]=0\n", 60 | " image2[:,0]=0\n", 61 | " image2[:,image2.shape[1]-1]=0\n", 62 | " image2=np.reshape(image2,(320,320))\n", 63 | " image[j,:,:]=image2\n", 64 | " j=j+1" 65 | ] 66 | }, 67 | { 68 | "cell_type": "code", 69 | "execution_count": 4, 70 | "metadata": { 71 | "collapsed": true 72 | }, 73 | "outputs": [], 74 | "source": [ 75 | "#从复合图分离\n", 76 | "'''\n", 77 | "之前的复合图像\n", 78 | "skeleton_img=skeleton_img*200#matplot为0-255绘图,0黑,255白。\n", 79 | "skeleton_img_liefeng=skeleton_img+image*55\n", 80 | "for n in range (0,19):\n", 81 | " #matplotlib.image.imsave(\"liefeng/%04.d.png\"%(n+1),skeleton_img[n,:,:])\n", 82 | " cv2.imwrite(\"liefeng/%04.d.png\"%(n+1),skeleton_img_liefeng[n,:,:])\n", 83 | "'''\n", 84 | "image_liefeng=np.zeros_like(image)\n", 85 | "image_gujia=np.zeros_like(image)\n", 86 | "image_gujia[image > 0.99]=1\n", 87 | "image_liefeng[image >0.1]=1" 88 | ] 89 | }, 90 | { 91 | "cell_type": "code", 92 | "execution_count": 5, 93 | "metadata": { 94 | "collapsed": true 95 | }, 96 | "outputs": [], 97 | "source": [ 98 | "Image_gujia=image_gujia*255#放大到0-255用于保存照片\n", 99 | "Image_liefeng=image_liefeng*255#放大的到0-255用于保存照片" 100 | ] 101 | }, 102 | { 103 | "cell_type": "code", 104 | "execution_count": 6, 105 | "metadata": { 106 | "collapsed": true 107 | }, 108 | "outputs": [], 109 | "source": [ 110 | "def get_gujia_point(image):\n", 111 | " \"接受骨架灰度照片(0-1),返回2维ndarray,记录所有骨架像素点位置\"\n", 112 | " gujia_P=np.nonzero(image)\n", 113 | " gujia_p=np.array(gujia_P)\n", 114 | " return gujia_p\n", 115 | "gujia_p4=get_gujia_point(image_gujia[3,:,:])" 116 | ] 117 | }, 118 | { 119 | "cell_type": "markdown", 120 | "metadata": {}, 121 | "source": [ 122 | "### 新增函数 get_angle()自动识别裂缝局部图裂缝的角度,用于后续把裂缝调整到竖直用" 123 | ] 124 | }, 125 | { 126 | "cell_type": "code", 127 | "execution_count": 113, 128 | "metadata": { 129 | "collapsed": true 130 | }, 131 | "outputs": [], 132 | "source": [ 133 | "#计算一张裂缝照片需要的旋转角\n", 134 | "def get_angle(Gj_for_w):\n", 135 | " gj_sum_lie=np.sum(Gj_for_w,axis=0)\n", 136 | " gj_sum_hang=np.sum(Gj_for_w,axis=1)\n", 137 | " lie=np.where(gj_sum_lie!=0)\n", 138 | " hang=np.where(gj_sum_hang!=0)\n", 139 | " img_h,img_w=Gj_for_w.shape\n", 140 | " point1_x=np.min(lie)\n", 141 | " point1_y=img_h-np.where(Gj_for_w[:,point1_x]!=0)[0][0]\n", 142 | " point2_x=np.max(lie)\n", 143 | " point2_y=img_h-np.where(Gj_for_w[:,point2_x]!=0)[0][0]\n", 144 | " if (point2_y-point1_y)==0:\n", 145 | " a=90\n", 146 | " else:\n", 147 | " tan_a=(point2_x-point1_x)/(point2_y-point1_y)\n", 148 | " a=atan(tan_a)*180/pi\n", 149 | " a=int(a)\n", 150 | " return a" 151 | ] 152 | }, 153 | { 154 | "cell_type": "markdown", 155 | "metadata": {}, 156 | "source": [ 157 | "### 新增函数rotate_bound_black_bg() 把照片逆时针旋转指定角度,且输入输出都是照片集,可以批量操作。\n", 158 | "\n", 159 | "注:输出后的照片尺寸比原尺寸大根号2倍" 160 | ] 161 | }, 162 | { 163 | "cell_type": "code", 164 | "execution_count": 114, 165 | "metadata": { 166 | "collapsed": true 167 | }, 168 | "outputs": [], 169 | "source": [ 170 | "#旋转函数\n", 171 | "def rotate_bound_black_bg(image_batch, angle):\n", 172 | " # grab the dimensions of the image and then determine the,image_batch为照片numpy3维数组,第一维代表个数,23代表高和宽\n", 173 | " # center\n", 174 | " (h, w) = image_batch.shape[1:3]\n", 175 | " (cX, cY) = (w // 2, h // 2)\n", 176 | " n=image_batch.shape[0]\n", 177 | " #旋转后照片会变大,最大倍就是转45度时的1.414倍,math.ceil向上取整\n", 178 | " H=ceil(h*1.415)\n", 179 | " W=ceil(w*1.415)\n", 180 | " rotation_batch=np.zeros([n,H,W])\n", 181 | " # grab the rotation matrix (applying the negative of the\n", 182 | " # angle to rotate clockwise), then grab the sine and cosine\n", 183 | " # (i.e., the rotation components of the matrix)\n", 184 | " # -angle位置参数为角度参数负值表示顺时针旋转; 1.0位置参数scale是调整尺寸比例(图像缩放参数),建议0.75\n", 185 | " for i in range(n):\n", 186 | " M = cv2.getRotationMatrix2D((cX, cY), angle[i], 1.0)\n", 187 | " cos = np.abs(M[0, 0])\n", 188 | " sin = np.abs(M[0, 1])\n", 189 | "\n", 190 | " # compute the new bounding dimensions of the image\n", 191 | " nW = int((h * sin) + (w * cos))\n", 192 | " nH = int((h * cos) + (w * sin))\n", 193 | "\n", 194 | " # adjust the rotation matrix to take into account translation\n", 195 | " M[0, 2] += (nW / 2) - cX\n", 196 | " M[1, 2] += (nH / 2) - cY\n", 197 | "\n", 198 | " # perform the actual rotation and return the image\n", 199 | " # borderValue 缺失背景填充色彩,此处为白色,可自定义\n", 200 | " rotation=cv2.warpAffine(image_batch[i,:,:], M, (nW, nH),borderValue=(0,0,0))\n", 201 | " pad_h=H-rotation.shape[0]\n", 202 | " pad_w=W-rotation.shape[1]\n", 203 | " rotation=np.pad(rotation,((0,pad_h),(0,pad_w)),'constant')\n", 204 | " rotation_batch[i,:,:]=rotation\n", 205 | " return rotation_batch\n", 206 | " # borderValue 缺省,默认是黑色(0, 0 , 0)\n", 207 | " # return cv2.warpAffine(image, M, (nW, nH))\n", 208 | " " 209 | ] 210 | }, 211 | { 212 | "cell_type": "code", 213 | "execution_count": 115, 214 | "metadata": { 215 | "collapsed": true 216 | }, 217 | "outputs": [], 218 | "source": [ 219 | "#返回一张照片的所有骨架像素点位置\n", 220 | "def get_gujia_point(image):\n", 221 | " \"接受骨架灰度照片(0-1),返回2维ndarray,记录所有骨架像素点位置\"\n", 222 | " gujia_P=np.nonzero(image)\n", 223 | " gujia_p=np.array(gujia_P)\n", 224 | " return gujia_p\n", 225 | "gujia_p4=get_gujia_point\n", 226 | "\n", 227 | "#返回所有框选照片\n", 228 | "def get_img_for_w(image_liefeng,point,w,h):\n", 229 | " \"输入image裂缝照片,point骨架点(2dimension,第一维代表纵坐标,第二位横坐标),w框选半宽,h框选半高,返回所有框选出照片,大小都相同\"\n", 230 | " n=point.shape[1]\n", 231 | " image_batch=np.zeros((n,2*h+1,2*w+1))\n", 232 | " angles=np.zeros(n)\n", 233 | " for i in range(0,n-1):\n", 234 | " #防止-h,-w后下标越界;上界可以越没关系\n", 235 | " if point[0,i]-h>=0 and point[1,i]-w>=0:\n", 236 | " img_for_w=image_liefeng[point[0,i]-h:point[0,i]+h,point[1,i]-w:point[1,i]+w]\n", 237 | " elif point[0,i]-h>=0 and point[1,i]-w<0:\n", 238 | " img_for_w=image_liefeng[point[0,i]-h:point[0,i]+h,0:point[1,i]+w]\n", 239 | " elif point[0,i]-h<0 and point[1,i]-w>=0:\n", 240 | " img_for_w=image_liefeng[0:point[0,i]+h,point[1,i]-w:point[1,i]+w]\n", 241 | " else:\n", 242 | " img_for_w=image_liefeng[0:point[0,i]+h,0:point[1,i]+w]\n", 243 | " img_h,img_w=img_for_w.shape\n", 244 | " pad_h=2*h+1-img_h\n", 245 | " pad_w=2*w+1-img_w\n", 246 | " img_for_w=np.pad(img_for_w,((0,pad_h),(0,pad_w)),'constant')\n", 247 | " image_batch[i,:,:]=img_for_w\n", 248 | " return image_batch\n", 249 | "#给出骨架和裂缝图片,统计点数,计算框选宽度\n", 250 | "def calculate_width(image_for_w,gujia_for_w):\n", 251 | " \"img_for_w框选的裂缝图,gj_for_w框选的骨架图,最后返回计算的平均宽度\"\n", 252 | " area=np.count_nonzero(image_for_w)\n", 253 | " length=np.count_nonzero(gujia_for_w)\n", 254 | " width=area/(length)\n", 255 | " return width\n", 256 | "\n", 257 | "def get_width(image_liefeng,image_gujia,w,h):\n", 258 | " gujia_p=get_gujia_point(image_gujia)\n", 259 | " width=get_w(image_liefeng,image_gujia,gujia_p,w,h)\n", 260 | " return width\n", 261 | "#width=get_width(image_liefeng[1,:,:],image_gujia[1,:,:],10,10)\n", 262 | "#width[400:450]\n", 263 | "#img_for_w=get_img_for_w(image_liefeng[3,:,:],gujia_p4,w,h) " 264 | ] 265 | }, 266 | { 267 | "cell_type": "markdown", 268 | "metadata": {}, 269 | "source": [ 270 | "### 定义get_img_and_angle_for_w()函数\n", 271 | "输入image裂缝照片,image骨架照片,w框选半宽,h框选半高,返回所有框选出照片和对应需要的旋转角\n", 272 | "\n", 273 | "\n", 274 | "在get_img_for_w()函数上新增返回旋转角度数组" 275 | ] 276 | }, 277 | { 278 | "cell_type": "code", 279 | "execution_count": 116, 280 | "metadata": { 281 | "collapsed": true 282 | }, 283 | "outputs": [], 284 | "source": [ 285 | "def get_img_and_angle_for_w(image_liefeng,image_gujia,w,h):\n", 286 | " \"输入image裂缝照片,image骨架照片,w框选半宽,h框选半高,返回所有框选出照片和旋转角\"\n", 287 | " point=get_gujia_point(image_gujia)\n", 288 | " n=point.shape[1]\n", 289 | " image_batch=np.zeros((n,2*h+1,2*w+1))\n", 290 | " angles=np.zeros(n)\n", 291 | " for i in range(0,n-1):\n", 292 | " #防止-h,-w后下标越界;上界可以越没关系\n", 293 | " if point[0,i]-h>=0 and point[1,i]-w>=0:\n", 294 | " img_for_w=image_liefeng[point[0,i]-h:point[0,i]+h,point[1,i]-w:point[1,i]+w]\n", 295 | " gj_for_w=image_gujia[point[0,i]-h:point[0,i]+h,point[1,i]-w:point[1,i]+w]\n", 296 | " elif point[0,i]-h>=0 and point[1,i]-w<0:\n", 297 | " img_for_w=image_liefeng[point[0,i]-h:point[0,i]+h,0:point[1,i]+w]\n", 298 | " gj_for_w=image_gujia[point[0,i]-h:point[0,i]+h,0:point[1,i]+w]\n", 299 | " elif point[0,i]-h<0 and point[1,i]-w>=0:\n", 300 | " img_for_w=image_liefeng[0:point[0,i]+h,point[1,i]-w:point[1,i]+w]\n", 301 | " gj_for_w=image_gujia[0:point[0,i]+h,point[1,i]-w:point[1,i]+w]\n", 302 | " else:\n", 303 | " img_for_w=image_liefeng[0:point[0,i]+h,0:point[1,i]+w]\n", 304 | " gj_for_w=image_gujia[0:point[0,i]+h,0:point[1,i]+w]\n", 305 | " img_h,img_w=img_for_w.shape\n", 306 | " angles[i]=get_angle(gj_for_w)\n", 307 | " pad_h=2*h+1-img_h\n", 308 | " pad_w=2*w+1-img_w\n", 309 | " img_for_w=np.pad(img_for_w,((0,pad_h),(0,pad_w)),'constant')\n", 310 | " image_batch[i,:,:]=img_for_w\n", 311 | " return image_batch, angles" 312 | ] 313 | }, 314 | { 315 | "cell_type": "markdown", 316 | "metadata": {}, 317 | "source": [ 318 | "### 用于测试get_img_and_angle_for_w\n", 319 | "测识结果保存在‘kuangxuan_angle’文件夹中\n", 320 | "该文件夹自己手动创建在运行目录\n", 321 | "运行正常" 322 | ] 323 | }, 324 | { 325 | "cell_type": "code", 326 | "execution_count": 121, 327 | "metadata": {}, 328 | "outputs": [], 329 | "source": [ 330 | "image_for_w,angles=get_img_and_angle_for_w(image_liefeng[0,:,:],image_gujia[0,:,:],30,30)\n", 331 | "Image_for_w=image_for_w*255\n", 332 | "for n in range(image_for_w.shape[0]) :\n", 333 | " #matplotlib.image.imsave(\"liefeng/gujia%04.d.png\"%(n+1),Image_gujia[n,:,:])\n", 334 | " cv2.imwrite(\"kuangxuan_angle/%04.d.png\"%(n+1),Image_for_w[n,:,:])" 335 | ] 336 | }, 337 | { 338 | "cell_type": "markdown", 339 | "metadata": {}, 340 | "source": [ 341 | "### 手动创建rotation文件夹在该运行目录 为后续实验用" 342 | ] 343 | }, 344 | { 345 | "cell_type": "markdown", 346 | "metadata": {}, 347 | "source": [ 348 | "### 测试旋转函数rotate_bound_black_bg(),结果保存在rotation文件夹中" 349 | ] 350 | }, 351 | { 352 | "cell_type": "code", 353 | "execution_count": 122, 354 | "metadata": { 355 | "collapsed": true 356 | }, 357 | "outputs": [], 358 | "source": [ 359 | "#测试用,不需运行\n", 360 | "image_rotation=rotate_bound_black_bg(image_for_w,angles)\n", 361 | "Image_rotation=iamge_rotation*255\n", 362 | "for n in range(iamge_rotation.shape[0]) :\n", 363 | " #matplotlib.image.imsave(\"liefeng/gujia%04.d.png\"%(n+1),Image_gujia[n,:,:])\n", 364 | " cv2.imwrite(\"rotation/%d/%04.d.png\"%(0,n+1),Iamge_rotation[n,:,:])" 365 | ] 366 | }, 367 | { 368 | "cell_type": "markdown", 369 | "metadata": {}, 370 | "source": [ 371 | "### 所有裂缝照片(20张)得到竖直的框选,存在rotation/n/文件夹下" 372 | ] 373 | }, 374 | { 375 | "cell_type": "code", 376 | "execution_count": 124, 377 | "metadata": { 378 | "collapsed": true 379 | }, 380 | "outputs": [], 381 | "source": [ 382 | "#创建用于存放照片的文件夹\n", 383 | "pathd=os.getcwd()+'\\\\rotation\\\\'\n", 384 | "for i in range(image_liefeng.shape[0]): \n", 385 | " os.mkdir(pathd+str(i))" 386 | ] 387 | }, 388 | { 389 | "cell_type": "code", 390 | "execution_count": 123, 391 | "metadata": {}, 392 | "outputs": [], 393 | "source": [ 394 | "#所有裂缝照片(20张)得到竖直的框选,存在rotation/n/文件夹下,第i张裂缝的所有框选照片存在文件夹rotation/i中\n", 395 | "for i in range(image_liefeng.shape[0]):\n", 396 | " image_for_w,angles=get_img_and_angle_for_w(image_liefeng[i,:,:],image_gujia[i,:,:],30,30)\n", 397 | " image_rotation=rotate_bound_black_bg(image_for_w,angles)\n", 398 | " Image_rotation=iamge_rotation*255\n", 399 | " for n in range(iamge_rotation.shape[0]) :\n", 400 | " #matplotlib.image.imsave(\"liefeng/gujia%04.d.png\"%(n+1),Image_gujia[n,:,:])\n", 401 | " cv2.imwrite(\"rotation/%d/%04.d.png\"%(i,n+1),Iamge_rotation[n,:,:])" 402 | ] 403 | }, 404 | { 405 | "cell_type": "code", 406 | "execution_count": 181, 407 | "metadata": { 408 | "collapsed": true 409 | }, 410 | "outputs": [], 411 | "source": [ 412 | "#没用,get_img_and_angle_for_w可以代替\n", 413 | "def get_img_angle(image_liefeng,image_gujia,h,w):\n", 414 | " \"输入一张裂缝照片,可以返回所有框选照片和对应的转正的旋转角,fabs别存放再ndarray中\"\n", 415 | " gujia_p=get_gujia_point(image_liefeng)\n", 416 | " img_for_w,angles=get_img_and_angle_for_w(image_liefeng,image_gujia,gujia_p,h,w)\n", 417 | " return img_for_w,angles" 418 | ] 419 | }, 420 | { 421 | "cell_type": "code", 422 | "execution_count": 34, 423 | "metadata": {}, 424 | "outputs": [ 425 | { 426 | "data": { 427 | "text/plain": [ 428 | "231" 429 | ] 430 | }, 431 | "execution_count": 34, 432 | "metadata": {}, 433 | "output_type": "execute_result" 434 | } 435 | ], 436 | "source": [ 437 | "img_kuangxuan_2.shape[0]" 438 | ] 439 | }, 440 | { 441 | "cell_type": "code", 442 | "execution_count": 39, 443 | "metadata": { 444 | "collapsed": true 445 | }, 446 | "outputs": [], 447 | "source": [ 448 | "#成功\n" 449 | ] 450 | }, 451 | { 452 | "cell_type": "code", 453 | "execution_count": 38, 454 | "metadata": {}, 455 | "outputs": [], 456 | "source": [ 457 | "#用于检查是否读入,cv2显式照片,0=黑,1=白\n", 458 | "cv2.namedWindow(\"Image\",0)\n", 459 | "cv2.imshow('Image',image_for_w[170,:,:])\n", 460 | "cv2.waitKey()\n", 461 | "cv2.destroyAllWindows()" 462 | ] 463 | }, 464 | { 465 | "cell_type": "code", 466 | "execution_count": 188, 467 | "metadata": {}, 468 | "outputs": [ 469 | { 470 | "ename": "TypeError", 471 | "evalue": "Argument 'angle' can not be treated as a double", 472 | "output_type": "error", 473 | "traceback": [ 474 | "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", 475 | "\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)", 476 | "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mrotate_bound_black_bg\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mimage_for_w\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mangles\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", 477 | "\u001b[1;32m\u001b[0m in \u001b[0;36mrotate_bound_black_bg\u001b[1;34m(image_batch, angle)\u001b[0m\n\u001b[0;32m 14\u001b[0m \u001b[1;31m# (i.e., the rotation components of the matrix)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 15\u001b[0m \u001b[1;31m# -angle位置参数为角度参数负值表示顺时针旋转; 1.0位置参数scale是调整尺寸比例(图像缩放参数),建议0.75\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 16\u001b[1;33m \u001b[0mM\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mcv2\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mgetRotationMatrix2D\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mcX\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mcY\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mangle\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m1.0\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 17\u001b[0m \u001b[0mcos\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mabs\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mM\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 18\u001b[0m \u001b[0msin\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mabs\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mM\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m1\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 478 | "\u001b[1;31mTypeError\u001b[0m: Argument 'angle' can not be treated as a double" 479 | ] 480 | } 481 | ], 482 | "source": [ 483 | "rotate_bound_black_bg(image_for_w,angles)" 484 | ] 485 | }, 486 | { 487 | "cell_type": "code", 488 | "execution_count": 85, 489 | "metadata": { 490 | "collapsed": true 491 | }, 492 | "outputs": [], 493 | "source": [ 494 | "#用于检查是否读入,cv2显式照片,0=黑,1=白\n", 495 | "cv2.namedWindow(\"Image\",0)\n", 496 | "cv2.imshow('Image',img_for_w[0,:,:])\n", 497 | "cv2.waitKey()\n", 498 | "cv2.destroyAllWindows()" 499 | ] 500 | }, 501 | { 502 | "cell_type": "code", 503 | "execution_count": 197, 504 | "metadata": {}, 505 | "outputs": [ 506 | { 507 | "data": { 508 | "text/plain": [ 509 | "(3128, 61, 61)" 510 | ] 511 | }, 512 | "execution_count": 197, 513 | "metadata": {}, 514 | "output_type": "execute_result" 515 | } 516 | ], 517 | "source": [] 518 | }, 519 | { 520 | "cell_type": "code", 521 | "execution_count": 172, 522 | "metadata": {}, 523 | "outputs": [ 524 | { 525 | "data": { 526 | "text/plain": [ 527 | "-48.012787504183336" 528 | ] 529 | }, 530 | "execution_count": 172, 531 | "metadata": {}, 532 | "output_type": "execute_result" 533 | } 534 | ], 535 | "source": [ 536 | "get_angle(gj_for_w[1,:,:])" 537 | ] 538 | }, 539 | { 540 | "cell_type": "code", 541 | "execution_count": 206, 542 | "metadata": { 543 | "collapsed": true 544 | }, 545 | "outputs": [], 546 | "source": [ 547 | "#用于检查是否读入,cv2显式照片,0=黑,1=白\n", 548 | "cv2.namedWindow(\"Image\",0)\n", 549 | "cv2.imshow('Image',image_for_w[50,:,:])\n", 550 | "cv2.waitKey()\n", 551 | "cv2.destroyAllWindows()" 552 | ] 553 | }, 554 | { 555 | "cell_type": "code", 556 | "execution_count": 191, 557 | "metadata": {}, 558 | "outputs": [ 559 | { 560 | "name": "stdout", 561 | "output_type": "stream", 562 | "text": [ 563 | "38.0\n" 564 | ] 565 | } 566 | ], 567 | "source": [ 568 | "print(angles[1])" 569 | ] 570 | } 571 | ], 572 | "metadata": { 573 | "kernelspec": { 574 | "display_name": "Python [conda env:pytorch2]", 575 | "language": "python", 576 | "name": "conda-env-pytorch2-py" 577 | }, 578 | "language_info": { 579 | "codemirror_mode": { 580 | "name": "ipython", 581 | "version": 3 582 | }, 583 | "file_extension": ".py", 584 | "mimetype": "text/x-python", 585 | "name": "python", 586 | "nbconvert_exporter": "python", 587 | "pygments_lexer": "ipython3", 588 | "version": "3.6.2" 589 | } 590 | }, 591 | "nbformat": 4, 592 | "nbformat_minor": 2 593 | } 594 | -------------------------------------------------------------------------------- /gujiatiqu.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "#import segmentation_models_pytorch as smp\n", 12 | "import os\n", 13 | "import numpy as np\n", 14 | "import cv2\n", 15 | "import matplotlib.pyplot as plt\n", 16 | "import albumentations as albu\n", 17 | "import torch\n", 18 | "import numpy as np\n", 19 | "from torch.utils.data import DataLoader\n", 20 | "from torch.utils.data import Dataset as BaseDataset\n", 21 | "os.environ['CUDA_VISIBLE_DEVICES'] = '0'" 22 | ] 23 | }, 24 | { 25 | "cell_type": "code", 26 | "execution_count": 2, 27 | "metadata": { 28 | "collapsed": true 29 | }, 30 | "outputs": [], 31 | "source": [ 32 | "#将图片路径写成列表,为后面cv2读入方便\n", 33 | "images_dir = 'Demo' \n", 34 | "ids=sorted(os.listdir(images_dir))\n", 35 | "images_fps=[os.path.join(images_dir, image_id) for image_id in ids]" 36 | ] 37 | }, 38 | { 39 | "cell_type": "code", 40 | "execution_count": 6, 41 | "metadata": { 42 | "collapsed": true 43 | }, 44 | "outputs": [], 45 | "source": [ 46 | "#批量处理,文件夹内20张照片读成np.array存入3维array‘image’,第一维代表第几张照片\n", 47 | "j=0\n", 48 | "image = np.zeros(shape=(len(images_fps),320,320))\n", 49 | "for i in images_fps:\n", 50 | " image1 = cv2.imread(i,1)\n", 51 | " image1 = cv2.cvtColor(image1, cv2.COLOR_BGR2RGB)\n", 52 | " #像素值变成0-1\n", 53 | " image2=image1[:,:,1]\n", 54 | " image2=image2-image2.min()\n", 55 | " image2=image2/image2.max()\n", 56 | " #照片周围变成空白像素,否则mat算法会报错\n", 57 | " image2[0,:]=0\n", 58 | " image2[image2.shape[0]-1,:]=0\n", 59 | " image2[:,0]=0\n", 60 | " image2[:,image2.shape[1]-1]=0\n", 61 | " image2=np.reshape(image2,(320,320))\n", 62 | " image[j,:,:]=image2\n", 63 | " j=j+1" 64 | ] 65 | }, 66 | { 67 | "cell_type": "code", 68 | "execution_count": 35, 69 | "metadata": { 70 | "collapsed": true 71 | }, 72 | "outputs": [], 73 | "source": [ 74 | "#这个cell没用,不需运行\n", 75 | "image5=cv2.imread('Fig0916(a)(region-filling-reflections).tif',1)\n", 76 | "image5 = cv2.cvtColor(image5, cv2.COLOR_BGR2RGB)\n", 77 | "image5=image5[:,:,0]\n", 78 | "image5=image5/image5.max()\n", 79 | "image5 = np.asarray(image5).astype(np.float32)\n", 80 | "plt.imshow(image5)\n", 81 | "#kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(3,3))\n", 82 | "\n", 83 | "#temp_img = cv2.dilate(image5,kernel)\n", 84 | "#temp_img = cv2.erode(temp_img,kernel)\n", 85 | "ret,temp_img = cv2.threshold(temp_img,127, 1, cv2.THRESH_BINARY)\n", 86 | "cv2.namedWindow(\"Image\",0)\n", 87 | "cv2.imshow('Image',temp_img)\n", 88 | "cv2.waitKey()\n", 89 | "cv2.destroyAllWindows()" 90 | ] 91 | }, 92 | { 93 | "cell_type": "code", 94 | "execution_count": 20, 95 | "metadata": { 96 | "collapsed": true 97 | }, 98 | "outputs": [], 99 | "source": [ 100 | "#用于检查是否读入,cv2显式照片\n", 101 | "cv2.namedWindow(\"Image\",0)\n", 102 | "cv2.imshow('Image',image[17,:,:])\n", 103 | "cv2.waitKey()\n", 104 | "cv2.destroyAllWindows()" 105 | ] 106 | }, 107 | { 108 | "cell_type": "code", 109 | "execution_count": 9, 110 | "metadata": { 111 | "collapsed": true 112 | }, 113 | "outputs": [], 114 | "source": [ 115 | "#!/usr/bin/env python\n", 116 | "# -*- coding: utf-8 -*-\n", 117 | "# cython: language_level=3\n", 118 | "from functools import reduce\n", 119 | "\n", 120 | "\n", 121 | "# =================================================================\n", 122 | "# MAT算法提取骨架\n", 123 | "# =================================================================\n", 124 | "\n", 125 | "\n", 126 | "def __mat_process_first(around_area: np.ndarray) -> bool:\n", 127 | " \"\"\"MAT算法步骤1\n", 128 | "\n", 129 | " 对于相邻像素区域:\n", 130 | " [\n", 131 | " [p9,p2,p3],\n", 132 | " [p8,p1,p4],\n", 133 | " [p7,p6,p5]\n", 134 | " ]\n", 135 | " 包括以下几个部分:\n", 136 | " a. 2 <=非零像素个数 <= 6\n", 137 | " b. 顺时针跳数 = 1\n", 138 | " c. p2 * p4 * p6 = 0\n", 139 | " d. p4 * p6 * p8 = 0\n", 140 | "\n", 141 | " :param around_area: numpy.array, 一个像素的相邻像素,为3*3\n", 142 | " :return: bool,是否满足以上所有条件\n", 143 | " \"\"\"\n", 144 | " result_list = list() # 保存所有步骤是否符合条件\n", 145 | " \"\"\"步骤a\"\"\"\n", 146 | " near_one_count = __near_pix_equal_one_count(around_area)\n", 147 | " result_list.append(2 <= near_one_count <= 6)\n", 148 | " \"\"\"步骤b\"\"\"\n", 149 | " result_list.append(__binary_transform_count(around_area) == 1)\n", 150 | " \"\"\"步骤c\"\"\"\n", 151 | " pix_2 = around_area[0][1]\n", 152 | " pix_4 = around_area[1][2]\n", 153 | " pix_6 = around_area[2][1]\n", 154 | " result_list.append(pix_2 * pix_4 * pix_6 == 0)\n", 155 | " \"\"\"步骤d\"\"\"\n", 156 | " pix_8 = around_area[1][0]\n", 157 | " result_list.append(pix_4 * pix_6 * pix_8 == 0)\n", 158 | "\n", 159 | " return bool(reduce(lambda x, y: x and y, result_list))\n", 160 | "\n", 161 | "\n", 162 | "def __mat_process_second(around_area: np.ndarray) -> bool:\n", 163 | " \"\"\"MAT算法步骤2\n", 164 | " 对于相邻像素区域:\n", 165 | " [\n", 166 | " [p9,p2,p3],\n", 167 | " [p8,p1,p4],\n", 168 | " [p7,p6,p5]\n", 169 | " ]\n", 170 | " 包括以下几个部分:\n", 171 | " a. 2 <=非零像素个数 <= 6\n", 172 | " b. 顺时针跳数 = 1\n", 173 | " c. p2 * p4 * p8 = 0\n", 174 | " d. p2 * p6 * p8 = 0\n", 175 | " :param around_area: numpy.array, 周围的区域\n", 176 | " :return: bool,是否全部子条件\n", 177 | " \"\"\"\n", 178 | " result_list = list() # 保存所有步骤是否符合条件\n", 179 | " \"\"\"步骤a\"\"\"\n", 180 | " near_one_count = __near_pix_equal_one_count(around_area)\n", 181 | " result_list.append(2 <= near_one_count <= 6)\n", 182 | " \"\"\"步骤b\"\"\"\n", 183 | " result_list.append(__binary_transform_count(around_area) == 1)\n", 184 | " \"\"\"步骤c\"\"\"\n", 185 | " pix_2 = around_area[0][1]\n", 186 | " pix_4 = around_area[1][2]\n", 187 | " pix_8 = around_area[1][0]\n", 188 | " pix_6 = around_area[2][1]\n", 189 | " result_list.append(pix_2 * pix_4 * pix_8 == 0)\n", 190 | " \"\"\"步骤d\"\"\"\n", 191 | " result_list.append(pix_2 * pix_6 * pix_8 == 0)\n", 192 | "\n", 193 | " return bool(reduce(lambda x, y: x and y, result_list))\n", 194 | "\n", 195 | "\n", 196 | "def __near_pix_equal_one_count(around_area: np.ndarray) -> int or np.int:\n", 197 | " \"\"\"计算相邻像素中为1的个数(不包括中间点)\n", 198 | "\n", 199 | " 即,对于相邻像素区域:\n", 200 | " [\n", 201 | " [p9,p2,p3],\n", 202 | " [p8,p1,p4],\n", 203 | " [p7,p6,p5]\n", 204 | " ]\n", 205 | " 统计出p1之外所有的1的个数\n", 206 | " :param around_area: numpy.array, 一个像素的相邻像素,为3*3\n", 207 | " :return int,像素为1的个数\n", 208 | " \"\"\"\n", 209 | " temp_around_area = np.copy(around_area)\n", 210 | " temp_around_area[1][1] = 0\n", 211 | " return int(np.sum(temp_around_area, dtype=np.int))\n", 212 | "\n", 213 | "\n", 214 | "def __binary_transform_count(around_area: np.ndarray) -> int or np.int:\n", 215 | " \"\"\"给定一个3*3的二进制图片,获取其顺时针的跳数(从0到1)\n", 216 | "\n", 217 | " 即,对于相邻像素区域:\n", 218 | " [\n", 219 | " [p9,p2,p3],\n", 220 | " [p8,p1,p4],\n", 221 | " [p7,p6,p5]\n", 222 | " ]\n", 223 | " 以p9,p2,p3,p4,p5,p6,p7,p8的顺序访问,如果是0到1,则为一跳\n", 224 | " :param around_area: numpy.array, 一个像素的相邻像素,为3*3\n", 225 | " :return int, 顺时针跳数\n", 226 | " \"\"\"\n", 227 | " def __next_index(current_coor: (int, int)) -> (int, int):\n", 228 | " \"\"\"给定当前位置,返回下一个位置\n", 229 | "\n", 230 | " :param current_coor: (int,int),当前位置\n", 231 | " :return: (int,int), 下一个位置\n", 232 | " \"\"\"\n", 233 | " '''四个方向的下一个位置'''\n", 234 | " right_next = (current_coor[0], current_coor[1] + 1)\n", 235 | " down_next = (current_coor[0] + 1, current_coor[1])\n", 236 | " left_next = (current_coor[0], current_coor[1] - 1)\n", 237 | " up_next = (current_coor[0] - 1, current_coor[1])\n", 238 | "\n", 239 | " \"\"\"按照指定的规则寻找,不报错则表示正确的方向\"\"\"\n", 240 | " next_coordinate_list = [right_next, down_next, left_next, up_next]\n", 241 | " for i, next_coordinate in enumerate(next_coordinate_list):\n", 242 | " try:\n", 243 | " around_area[next_coordinate]\n", 244 | " except IndexError:\n", 245 | " continue\n", 246 | " else:\n", 247 | " '''如果该点已经走过'''\n", 248 | " if is_walked[next_coordinate[0], next_coordinate[1]]:\n", 249 | " continue\n", 250 | " else:\n", 251 | " is_walked[next_coordinate[0], next_coordinate[1]] = True\n", 252 | " return next_coordinate\n", 253 | "\n", 254 | " is_walked = np.full_like(around_area, False) # 用于标识该点是否已经走过\n", 255 | " is_walked[1][1] = True\n", 256 | " transform_count = 0 # 用于记录跳数\n", 257 | " \"\"\"循环对比\"\"\"\n", 258 | " last_pix = around_area[0][0] # 上一个的值\n", 259 | " current_coordinate = (0, 1)\n", 260 | " while current_coordinate != (0, 0):\n", 261 | " current_pix = around_area[current_coordinate[0], current_coordinate[1]]\n", 262 | " if last_pix == 0 and current_pix == 1:\n", 263 | " transform_count += 1\n", 264 | "\n", 265 | " last_pix = current_pix\n", 266 | " current_coordinate = __next_index(current_coordinate)\n", 267 | "\n", 268 | " '''当循环到第一个点时再对比一次'''\n", 269 | " current_pix = around_area[current_coordinate[0], current_coordinate[0]]\n", 270 | " if last_pix == 0 and current_pix == 1:\n", 271 | " transform_count += 1\n", 272 | "\n", 273 | " return transform_count\n", 274 | "\n", 275 | "\n", 276 | "def __remove_pix_by_coordination(img: np.ndarray, points: list):\n", 277 | " \"\"\"给定坐标的list,删除图像上的点(实际就是标记为0)\n", 278 | "\n", 279 | " :param img: numpy.array,图像\n", 280 | " :param points: List[(int,int)]\n", 281 | " \"\"\"\n", 282 | " for single_coordination in points:\n", 283 | " i_row, i_col = single_coordination\n", 284 | " img[i_row][i_col] = 0\n", 285 | "\n", 286 | "\n", 287 | "def __get_remove_points(img: np.ndarray, func) -> [(int, int)]:\n", 288 | " \"\"\"给定图像以及,删除点的规则,返回要删除的点\n", 289 | "\n", 290 | " :param img: numpy.array, 原图像\n", 291 | " :param func: function, 规则,也就是一个函数\n", 292 | " :return: List[(int,int)],坐标的list\n", 293 | " \"\"\"\n", 294 | " remove_points_list = list()\n", 295 | " temp_img = img\n", 296 | " img_iter = np.nditer(temp_img, flags=[\"multi_index\"])\n", 297 | " while not img_iter.finished:\n", 298 | " current_pix = img_iter[0]\n", 299 | " i_row, i_col = img_iter.multi_index\n", 300 | " img_iter.iternext()\n", 301 | " '''如果是背景点则直接跳过'''\n", 302 | " if current_pix != 1:\n", 303 | " continue\n", 304 | "\n", 305 | " \"\"\"如果是前景点\"\"\"\n", 306 | " around_area = temp_img[i_row - 1:i_row + 2, i_col - 1:i_col + 2]\n", 307 | " if func(around_area):\n", 308 | " remove_points_list.append((i_row, i_col))\n", 309 | "\n", 310 | " img_iter.iternext()\n", 311 | " return remove_points_list\n", 312 | "\n", 313 | "\n", 314 | "def get_img_skeleton_by_mat(img: np.ndarray) -> np.ndarray:\n", 315 | " \"\"\"根据字体的图像得到字的骨架\n", 316 | "\n", 317 | " :param img, numpy.array, 原图片\n", 318 | " :raise ValueError\n", 319 | " - 图片不为单通道\n", 320 | " - 图片并未归一化\n", 321 | " - 图片并未标准化\n", 322 | " :return: numpy.array, 骨架图\n", 323 | " \"\"\"\n", 324 | " '''检验图片是否是单通道'''\n", 325 | " if len(img.shape) != 2:\n", 326 | " raise ValueError(\"该图片不是单通道\")\n", 327 | " \"\"\"检验标准化\"\"\"\n", 328 | " if img.max() > 1:\n", 329 | " raise ValueError(\"该图片并未标准化\")\n", 330 | " \"\"\"检验二值化\"\"\"\n", 331 | " if (np.unique(img.flatten()) != (0, 1)).all():\n", 332 | " raise ValueError(\"该函数并未二值化\")\n", 333 | "\n", 334 | " temp_img = img.copy()\n", 335 | " \"\"\"遍历每一个像素点\"\"\"\n", 336 | " is_remove_flag = True # 表示是否继续删除的标志\n", 337 | " i_round = 1 # 记录迭代的轮数\n", 338 | " while is_remove_flag:\n", 339 | " is_remove_flag = False\n", 340 | " print(\"正在执行MAT算法的第{}轮\".format(i_round))\n", 341 | " \"\"\"执行步骤1\"\"\"\n", 342 | " remove_points = __get_remove_points(temp_img, __mat_process_first)\n", 343 | " if len(remove_points) != 0:\n", 344 | " is_remove_flag = True\n", 345 | " __remove_pix_by_coordination(temp_img, remove_points)\n", 346 | "\n", 347 | " \"\"\"执行步骤2\"\"\"\n", 348 | " remove_points = __get_remove_points(temp_img, __mat_process_second)\n", 349 | " if len(remove_points) != 0:\n", 350 | " is_remove_flag = True\n", 351 | " __remove_pix_by_coordination(temp_img, remove_points)\n", 352 | "\n", 353 | " i_round += 1\n", 354 | "\n", 355 | " return temp_img\n" 356 | ] 357 | }, 358 | { 359 | "cell_type": "code", 360 | "execution_count": 10, 361 | "metadata": {}, 362 | "outputs": [ 363 | { 364 | "name": "stdout", 365 | "output_type": "stream", 366 | "text": [ 367 | "正在执行MAT算法的第1轮\n", 368 | "正在执行MAT算法的第2轮\n", 369 | "正在执行MAT算法的第3轮\n", 370 | "正在执行MAT算法的第4轮\n", 371 | "正在执行MAT算法的第5轮\n", 372 | "正在执行MAT算法的第6轮\n", 373 | "正在执行MAT算法的第1轮\n", 374 | "正在执行MAT算法的第2轮\n", 375 | "正在执行MAT算法的第3轮\n", 376 | "正在执行MAT算法的第4轮\n", 377 | "正在执行MAT算法的第5轮\n", 378 | "正在执行MAT算法的第1轮\n", 379 | "正在执行MAT算法的第2轮\n", 380 | "正在执行MAT算法的第3轮\n", 381 | "正在执行MAT算法的第4轮\n", 382 | "正在执行MAT算法的第5轮\n", 383 | "正在执行MAT算法的第6轮\n", 384 | "正在执行MAT算法的第1轮\n", 385 | "正在执行MAT算法的第2轮\n", 386 | "正在执行MAT算法的第3轮\n", 387 | "正在执行MAT算法的第4轮\n", 388 | "正在执行MAT算法的第5轮\n", 389 | "正在执行MAT算法的第1轮\n", 390 | "正在执行MAT算法的第2轮\n", 391 | "正在执行MAT算法的第3轮\n", 392 | "正在执行MAT算法的第4轮\n", 393 | "正在执行MAT算法的第5轮\n", 394 | "正在执行MAT算法的第1轮\n", 395 | "正在执行MAT算法的第2轮\n", 396 | "正在执行MAT算法的第3轮\n", 397 | "正在执行MAT算法的第4轮\n", 398 | "正在执行MAT算法的第5轮\n", 399 | "正在执行MAT算法的第6轮\n", 400 | "正在执行MAT算法的第7轮\n", 401 | "正在执行MAT算法的第8轮\n", 402 | "正在执行MAT算法的第9轮\n", 403 | "正在执行MAT算法的第10轮\n", 404 | "正在执行MAT算法的第11轮\n", 405 | "正在执行MAT算法的第12轮\n", 406 | "正在执行MAT算法的第13轮\n", 407 | "正在执行MAT算法的第14轮\n", 408 | "正在执行MAT算法的第15轮\n", 409 | "正在执行MAT算法的第16轮\n", 410 | "正在执行MAT算法的第17轮\n", 411 | "正在执行MAT算法的第18轮\n", 412 | "正在执行MAT算法的第19轮\n", 413 | "正在执行MAT算法的第20轮\n", 414 | "正在执行MAT算法的第1轮\n", 415 | "正在执行MAT算法的第2轮\n", 416 | "正在执行MAT算法的第3轮\n", 417 | "正在执行MAT算法的第4轮\n", 418 | "正在执行MAT算法的第5轮\n", 419 | "正在执行MAT算法的第6轮\n", 420 | "正在执行MAT算法的第7轮\n", 421 | "正在执行MAT算法的第8轮\n", 422 | "正在执行MAT算法的第9轮\n", 423 | "正在执行MAT算法的第10轮\n", 424 | "正在执行MAT算法的第11轮\n", 425 | "正在执行MAT算法的第12轮\n", 426 | "正在执行MAT算法的第13轮\n", 427 | "正在执行MAT算法的第1轮\n", 428 | "正在执行MAT算法的第2轮\n", 429 | "正在执行MAT算法的第3轮\n", 430 | "正在执行MAT算法的第4轮\n", 431 | "正在执行MAT算法的第5轮\n", 432 | "正在执行MAT算法的第6轮\n", 433 | "正在执行MAT算法的第7轮\n", 434 | "正在执行MAT算法的第8轮\n", 435 | "正在执行MAT算法的第9轮\n", 436 | "正在执行MAT算法的第10轮\n", 437 | "正在执行MAT算法的第11轮\n", 438 | "正在执行MAT算法的第12轮\n", 439 | "正在执行MAT算法的第13轮\n", 440 | "正在执行MAT算法的第14轮\n", 441 | "正在执行MAT算法的第15轮\n", 442 | "正在执行MAT算法的第16轮\n", 443 | "正在执行MAT算法的第1轮\n", 444 | "正在执行MAT算法的第2轮\n", 445 | "正在执行MAT算法的第3轮\n", 446 | "正在执行MAT算法的第4轮\n", 447 | "正在执行MAT算法的第5轮\n", 448 | "正在执行MAT算法的第6轮\n", 449 | "正在执行MAT算法的第7轮\n", 450 | "正在执行MAT算法的第8轮\n", 451 | "正在执行MAT算法的第9轮\n", 452 | "正在执行MAT算法的第10轮\n", 453 | "正在执行MAT算法的第11轮\n", 454 | "正在执行MAT算法的第12轮\n", 455 | "正在执行MAT算法的第13轮\n", 456 | "正在执行MAT算法的第14轮\n", 457 | "正在执行MAT算法的第15轮\n", 458 | "正在执行MAT算法的第16轮\n", 459 | "正在执行MAT算法的第17轮\n", 460 | "正在执行MAT算法的第1轮\n", 461 | "正在执行MAT算法的第2轮\n", 462 | "正在执行MAT算法的第3轮\n", 463 | "正在执行MAT算法的第4轮\n", 464 | "正在执行MAT算法的第5轮\n", 465 | "正在执行MAT算法的第6轮\n", 466 | "正在执行MAT算法的第7轮\n", 467 | "正在执行MAT算法的第8轮\n", 468 | "正在执行MAT算法的第9轮\n", 469 | "正在执行MAT算法的第10轮\n", 470 | "正在执行MAT算法的第11轮\n", 471 | "正在执行MAT算法的第12轮\n", 472 | "正在执行MAT算法的第13轮\n", 473 | "正在执行MAT算法的第14轮\n", 474 | "正在执行MAT算法的第15轮\n", 475 | "正在执行MAT算法的第16轮\n", 476 | "正在执行MAT算法的第17轮\n", 477 | "正在执行MAT算法的第18轮\n", 478 | "正在执行MAT算法的第1轮\n", 479 | "正在执行MAT算法的第2轮\n", 480 | "正在执行MAT算法的第3轮\n", 481 | "正在执行MAT算法的第4轮\n", 482 | "正在执行MAT算法的第5轮\n", 483 | "正在执行MAT算法的第6轮\n", 484 | "正在执行MAT算法的第7轮\n", 485 | "正在执行MAT算法的第8轮\n", 486 | "正在执行MAT算法的第9轮\n", 487 | "正在执行MAT算法的第1轮\n", 488 | "正在执行MAT算法的第2轮\n", 489 | "正在执行MAT算法的第3轮\n", 490 | "正在执行MAT算法的第4轮\n", 491 | "正在执行MAT算法的第5轮\n", 492 | "正在执行MAT算法的第6轮\n", 493 | "正在执行MAT算法的第7轮\n", 494 | "正在执行MAT算法的第8轮\n", 495 | "正在执行MAT算法的第9轮\n", 496 | "正在执行MAT算法的第1轮\n", 497 | "正在执行MAT算法的第2轮\n", 498 | "正在执行MAT算法的第3轮\n", 499 | "正在执行MAT算法的第4轮\n", 500 | "正在执行MAT算法的第5轮\n", 501 | "正在执行MAT算法的第1轮\n", 502 | "正在执行MAT算法的第2轮\n", 503 | "正在执行MAT算法的第3轮\n", 504 | "正在执行MAT算法的第4轮\n", 505 | "正在执行MAT算法的第5轮\n", 506 | "正在执行MAT算法的第1轮\n", 507 | "正在执行MAT算法的第2轮\n", 508 | "正在执行MAT算法的第3轮\n", 509 | "正在执行MAT算法的第4轮\n", 510 | "正在执行MAT算法的第5轮\n", 511 | "正在执行MAT算法的第6轮\n", 512 | "正在执行MAT算法的第7轮\n", 513 | "正在执行MAT算法的第8轮\n", 514 | "正在执行MAT算法的第9轮\n", 515 | "正在执行MAT算法的第10轮\n", 516 | "正在执行MAT算法的第11轮\n", 517 | "正在执行MAT算法的第12轮\n", 518 | "正在执行MAT算法的第13轮\n", 519 | "正在执行MAT算法的第14轮\n", 520 | "正在执行MAT算法的第15轮\n", 521 | "正在执行MAT算法的第16轮\n", 522 | "正在执行MAT算法的第17轮\n", 523 | "正在执行MAT算法的第18轮\n", 524 | "正在执行MAT算法的第1轮\n", 525 | "正在执行MAT算法的第2轮\n", 526 | "正在执行MAT算法的第3轮\n", 527 | "正在执行MAT算法的第4轮\n", 528 | "正在执行MAT算法的第5轮\n", 529 | "正在执行MAT算法的第6轮\n", 530 | "正在执行MAT算法的第7轮\n", 531 | "正在执行MAT算法的第8轮\n", 532 | "正在执行MAT算法的第9轮\n", 533 | "正在执行MAT算法的第10轮\n", 534 | "正在执行MAT算法的第11轮\n", 535 | "正在执行MAT算法的第12轮\n", 536 | "正在执行MAT算法的第13轮\n", 537 | "正在执行MAT算法的第14轮\n", 538 | "正在执行MAT算法的第15轮\n", 539 | "正在执行MAT算法的第16轮\n", 540 | "正在执行MAT算法的第17轮\n", 541 | "正在执行MAT算法的第18轮\n", 542 | "正在执行MAT算法的第19轮\n", 543 | "正在执行MAT算法的第20轮\n", 544 | "正在执行MAT算法的第21轮\n", 545 | "正在执行MAT算法的第22轮\n", 546 | "正在执行MAT算法的第23轮\n", 547 | "正在执行MAT算法的第24轮\n", 548 | "正在执行MAT算法的第25轮\n", 549 | "正在执行MAT算法的第26轮\n", 550 | "正在执行MAT算法的第27轮\n", 551 | "正在执行MAT算法的第28轮\n", 552 | "正在执行MAT算法的第29轮\n", 553 | "正在执行MAT算法的第30轮\n", 554 | "正在执行MAT算法的第31轮\n", 555 | "正在执行MAT算法的第32轮\n", 556 | "正在执行MAT算法的第1轮\n", 557 | "正在执行MAT算法的第2轮\n", 558 | "正在执行MAT算法的第3轮\n", 559 | "正在执行MAT算法的第4轮\n", 560 | "正在执行MAT算法的第5轮\n", 561 | "正在执行MAT算法的第6轮\n", 562 | "正在执行MAT算法的第7轮\n", 563 | "正在执行MAT算法的第8轮\n", 564 | "正在执行MAT算法的第9轮\n", 565 | "正在执行MAT算法的第10轮\n", 566 | "正在执行MAT算法的第11轮\n", 567 | "正在执行MAT算法的第12轮\n", 568 | "正在执行MAT算法的第13轮\n", 569 | "正在执行MAT算法的第14轮\n", 570 | "正在执行MAT算法的第15轮\n", 571 | "正在执行MAT算法的第1轮\n", 572 | "正在执行MAT算法的第2轮\n", 573 | "正在执行MAT算法的第3轮\n", 574 | "正在执行MAT算法的第4轮\n", 575 | "正在执行MAT算法的第5轮\n", 576 | "正在执行MAT算法的第6轮\n", 577 | "正在执行MAT算法的第7轮\n", 578 | "正在执行MAT算法的第8轮\n", 579 | "正在执行MAT算法的第9轮\n", 580 | "正在执行MAT算法的第10轮\n", 581 | "正在执行MAT算法的第11轮\n", 582 | "正在执行MAT算法的第12轮\n", 583 | "正在执行MAT算法的第13轮\n", 584 | "正在执行MAT算法的第14轮\n", 585 | "正在执行MAT算法的第1轮\n", 586 | "正在执行MAT算法的第2轮\n", 587 | "正在执行MAT算法的第3轮\n", 588 | "正在执行MAT算法的第4轮\n", 589 | "正在执行MAT算法的第5轮\n", 590 | "正在执行MAT算法的第6轮\n", 591 | "正在执行MAT算法的第7轮\n", 592 | "正在执行MAT算法的第8轮\n", 593 | "正在执行MAT算法的第9轮\n", 594 | "正在执行MAT算法的第10轮\n", 595 | "正在执行MAT算法的第11轮\n", 596 | "正在执行MAT算法的第12轮\n", 597 | "正在执行MAT算法的第13轮\n", 598 | "正在执行MAT算法的第14轮\n", 599 | "正在执行MAT算法的第15轮\n", 600 | "正在执行MAT算法的第16轮\n", 601 | "正在执行MAT算法的第17轮\n", 602 | "正在执行MAT算法的第18轮\n", 603 | "正在执行MAT算法的第19轮\n" 604 | ] 605 | } 606 | ], 607 | "source": [ 608 | "#一次提取20张裂缝图片骨架\n", 609 | "skeleton_img = np.zeros(shape=(20,320,320))\n", 610 | "for i in range (0,19):\n", 611 | " skeleton_img[i,:,:] = get_img_skeleton_by_mat(image[i,:,:])" 612 | ] 613 | }, 614 | { 615 | "cell_type": "code", 616 | "execution_count": 14, 617 | "metadata": { 618 | "collapsed": true 619 | }, 620 | "outputs": [], 621 | "source": [ 622 | "skeleton_img=skeleton_img*200#matplot为0-255绘图,0白色,255黑色。原先最大值为1.\n", 623 | "skeleton_img_liefeng=skeleton_img+image*55\n", 624 | "for n in range (0,19):\n", 625 | " #matplotlib.image.imsave(\"liefeng/%04.d.png\"%(n+1),skeleton_img[n,:,:])\n", 626 | " cv2.imwrite(\"liefeng/%04.d.png\"%(n+1),skeleton_img_liefeng[n,:,:])" 627 | ] 628 | }, 629 | { 630 | "cell_type": "code", 631 | "execution_count": 38, 632 | "metadata": { 633 | "collapsed": true 634 | }, 635 | "outputs": [], 636 | "source": [ 637 | "#将图片路径写成列表,为后面cv2读入方便\n", 638 | "images_dir = 'liefeng' \n", 639 | "ids=sorted(os.listdir(images_dir))\n", 640 | "images_fps=[os.path.join(images_dir, image_id) for image_id in ids]\n", 641 | "#批量处理,文件夹内20张照片读成np.array存入3维array‘image’,第一维代表第几张照片\n", 642 | "j=0\n", 643 | "image_done = np.zeros(shape=(len(images_fps),320,320))\n", 644 | "for i in images_fps:\n", 645 | " image1 = cv2.imread(i,1)\n", 646 | " image1 = cv2.cvtColor(image1, cv2.COLOR_BGR2RGB)\n", 647 | " #像素值变成0-1\n", 648 | " image2=image1[:,:,1]\n", 649 | " image2=image2-image2.min()\n", 650 | " image2=image2/image2.max()\n", 651 | " #照片周围变成空白像素,否则mat算法会报错\n", 652 | " image_done[j,:,:]=image2\n", 653 | " j=j+1" 654 | ] 655 | }, 656 | { 657 | "cell_type": "code", 658 | "execution_count": 50, 659 | "metadata": { 660 | "collapsed": true 661 | }, 662 | "outputs": [], 663 | "source": [ 664 | "#用于检查是否读入,cv2显式照片\n", 665 | "image_done[9,:,:]=image_done[9,]\n", 666 | "cv2.namedWindow(\"Image\",0)\n", 667 | "cv2.imshow('Image',image_done[9,:,:])\n", 668 | "cv2.waitKey()\n", 669 | "cv2.destroyAllWindows()" 670 | ] 671 | } 672 | ], 673 | "metadata": { 674 | "kernelspec": { 675 | "display_name": "Python [conda env:pytorch2]", 676 | "language": "python", 677 | "name": "conda-env-pytorch2-py" 678 | }, 679 | "language_info": { 680 | "codemirror_mode": { 681 | "name": "ipython", 682 | "version": 3 683 | }, 684 | "file_extension": ".py", 685 | "mimetype": "text/x-python", 686 | "name": "python", 687 | "nbconvert_exporter": "python", 688 | "pygments_lexer": "ipython3", 689 | "version": "3.6.2" 690 | } 691 | }, 692 | "nbformat": 4, 693 | "nbformat_minor": 2 694 | } 695 | -------------------------------------------------------------------------------- /try.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "#import segmentation_models_pytorch as smp\n", 12 | "import os\n", 13 | "import numpy as np\n", 14 | "import cv2\n", 15 | "import matplotlib.pyplot as plt\n", 16 | "import albumentations as albu\n", 17 | "import torch\n", 18 | "import numpy as np\n", 19 | "from torch.utils.data import DataLoader\n", 20 | "from torch.utils.data import Dataset as BaseDataset\n", 21 | "os.environ['CUDA_VISIBLE_DEVICES'] = '0'" 22 | ] 23 | }, 24 | { 25 | "cell_type": "code", 26 | "execution_count": 3, 27 | "metadata": { 28 | "collapsed": true 29 | }, 30 | "outputs": [], 31 | "source": [ 32 | "import numpy as np\n", 33 | "import matplotlib.pyplot as plt\n", 34 | "import cv2" 35 | ] 36 | }, 37 | { 38 | "cell_type": "code", 39 | "execution_count": 4, 40 | "metadata": {}, 41 | "outputs": [ 42 | { 43 | "ename": "NameError", 44 | "evalue": "name 'img' is not defined", 45 | "output_type": "error", 46 | "traceback": [ 47 | "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", 48 | "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", 49 | "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[0moutput\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mzeros\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m320\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m320\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m3\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mdtype\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mint\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[0mterm\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mimg\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mnewaxis\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 3\u001b[0m \u001b[0moutput\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mconcatenate\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0moutput\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mterm\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0maxis\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;36m0\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0moutput\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mshape\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 50 | "\u001b[1;31mNameError\u001b[0m: name 'img' is not defined" 51 | ] 52 | } 53 | ], 54 | "source": [ 55 | "output = np.zeros([1,320,320,3], dtype=int)\n", 56 | "term = img[np.newaxis,:,:,:]\n", 57 | "output = np.concatenate((output,term),axis = 0)\n", 58 | "print(output.shape)" 59 | ] 60 | }, 61 | { 62 | "cell_type": "code", 63 | "execution_count": 4, 64 | "metadata": { 65 | "collapsed": true 66 | }, 67 | "outputs": [], 68 | "source": [ 69 | "# Define the dataset\n", 70 | "class Dataset(BaseDataset):\n", 71 | " \"\"\"\n", 72 | " Args:\n", 73 | " images_dir (str): path to images folder\n", 74 | " masks_dir (str): path to segmentation masks folder\n", 75 | " class_values (list): values of classes to extract from segmentation mask\n", 76 | " augmentation (albumentations.Compose): data transfromation pipeline \n", 77 | " (e.g. flip, scale, etc.)\n", 78 | " preprocessing (albumentations.Compose): data preprocessing \n", 79 | " (e.g. noralization, shape manipulation, etc.)\n", 80 | " Note: we don't need mask when testing.\n", 81 | " \n", 82 | " \"\"\"\n", 83 | " \n", 84 | " CLASSES = ['crack']\n", 85 | " \n", 86 | " def __init__(\n", 87 | " self, \n", 88 | " images_dir, \n", 89 | " classes=None, \n", 90 | " augmentation=None, \n", 91 | " preprocessing=None,\n", 92 | " ):\n", 93 | " self.ids = sorted(os.listdir(images_dir))\n", 94 | " self.images_fps = [os.path.join(images_dir, image_id) for image_id in self.ids]\n", 95 | " \n", 96 | " # convert str names to class values on masks\n", 97 | " self.class_values = [self.CLASSES.index(cls.lower()) for cls in classes]\n", 98 | " \n", 99 | " self.augmentation = augmentation\n", 100 | " self.preprocessing = preprocessing\n", 101 | " \n", 102 | " def __getitem__(self, i):\n", 103 | " \n", 104 | " # read data\n", 105 | " image = cv2.imread(self.images_fps[i],1)\n", 106 | " image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n", 107 | " # apply augmentations\n", 108 | " if self.augmentation:\n", 109 | " sample = self.augmentation(image=image)\n", 110 | " image = sample['image']\n", 111 | " if self.preprocessing:\n", 112 | " sample = self.preprocessing(image=image)\n", 113 | " image = sample['image']\n", 114 | " image = testdataprocessing(image.transpose(1,2,0))\n", 115 | " image = image.transpose(0,3,1,2)\n", 116 | " return image\n", 117 | " \n", 118 | " def __len__(self):\n", 119 | " return len(self.ids)" 120 | ] 121 | }, 122 | { 123 | "cell_type": "code", 124 | "execution_count": 4, 125 | "metadata": {}, 126 | "outputs": [ 127 | { 128 | "ename": "NameError", 129 | "evalue": "name 'Dataset' is not defined", 130 | "output_type": "error", 131 | "traceback": [ 132 | "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", 133 | "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", 134 | "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[0;32m 25\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0malbu\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mCompose\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0m_transform\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 26\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 27\u001b[1;33m test_dataset = Dataset(\n\u001b[0m\u001b[0;32m 28\u001b[0m \u001b[0mx_test_dir\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 29\u001b[0m \u001b[0maugmentation\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mNone\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;31m# for test, we just set augmentation to None\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 135 | "\u001b[1;31mNameError\u001b[0m: name 'Dataset' is not defined" 136 | ] 137 | } 138 | ], 139 | "source": [ 140 | "# create test dataset\n", 141 | "def get_validation_augmentation():\n", 142 | " \"\"\"You can put some augmentations on here\"\"\"\n", 143 | " test_transform = [\n", 144 | " albu.Resize(320,320),\n", 145 | " ]\n", 146 | " return albu.Compose(test_transform)\n", 147 | "def to_tensor(x, **kwargs):\n", 148 | " return x.transpose(2, 0, 1).astype('float32')\n", 149 | "def get_preprocessing(preprocessing_fn):\n", 150 | " \"\"\"Construct preprocessing transform\n", 151 | " \n", 152 | " Args:\n", 153 | " preprocessing_fn (callbale): data normalization function \n", 154 | " (can be specific for each pretrained neural network)\n", 155 | " Return:\n", 156 | " transform: albumentations.Compose\n", 157 | " \n", 158 | " \"\"\"\n", 159 | " \n", 160 | " _transform = [\n", 161 | " albu.Lambda(image=preprocessing_fn),\n", 162 | " albu.Lambda(image=to_tensor),\n", 163 | " ]\n", 164 | " return albu.Compose(_transform)\n", 165 | " \n", 166 | "test_dataset = Dataset(\n", 167 | " x_test_dir, \n", 168 | " augmentation=None, # for test, we just set augmentation to None\n", 169 | " preprocessing=get_preprocessing(preprocessing_fn),\n", 170 | " classes=CLASSES,\n", 171 | ")\n" 172 | ] 173 | }, 174 | { 175 | "cell_type": "code", 176 | "execution_count": 10, 177 | "metadata": { 178 | "collapsed": true 179 | }, 180 | "outputs": [], 181 | "source": [ 182 | "#! /usr/bin/python\n", 183 | "# _*_ coding: utf-8 _*_\n", 184 | "__author__ = 'Jeffery'\n", 185 | "\n", 186 | "class Student(object):\n", 187 | " \"\"\"\n", 188 | " Student class\n", 189 | " \"\"\"\n", 190 | "\n", 191 | " # student_number是一个类属性, 可通过类访问,也可通过对象访问,所有对象共享该表量\n", 192 | " student_number = 0\n", 193 | "\n", 194 | " # 方法可有默认参数、可变参数、关键字参数和命名关键字参数\n", 195 | " def __init__(self, sid, name, score):\n", 196 | " \"\"\"\n", 197 | " Student class init method\n", 198 | " \"\"\"\n", 199 | " Student.student_number += 1\n", 200 | " self.__id = sid\n", 201 | " self.name = name\n", 202 | " self.score = score\n", 203 | "\n", 204 | " def print_info(self):\n", 205 | " \"\"\"\n", 206 | " get Student info\n", 207 | " \"\"\"\n", 208 | " print('%s: %s' % (self.name, self.score), end=' ')" 209 | ] 210 | }, 211 | { 212 | "cell_type": "code", 213 | "execution_count": 11, 214 | "metadata": {}, 215 | "outputs": [ 216 | { 217 | "name": "stdout", 218 | "output_type": "stream", 219 | "text": [ 220 | "Bart Simpson: 59 1\n", 221 | "1\n" 222 | ] 223 | } 224 | ], 225 | "source": [ 226 | "bart = Student('001', 'Bart Simpson', 59)\n", 227 | "bart.print_info()\n", 228 | "print(bart.student_number) # 1\n", 229 | "print(Student.student_number) # 1\n" 230 | ] 231 | }, 232 | { 233 | "cell_type": "code", 234 | "execution_count": 12, 235 | "metadata": { 236 | "scrolled": true 237 | }, 238 | "outputs": [ 239 | { 240 | "name": "stdout", 241 | "output_type": "stream", 242 | "text": [ 243 | "Lisa Simpson: 87 2\n", 244 | "2\n" 245 | ] 246 | } 247 | ], 248 | "source": [ 249 | "\n", 250 | "lisa = Student('002', 'Lisa Simpson', 87)\n", 251 | "lisa.print_info()\n", 252 | "print(bart.student_number) # 2\n", 253 | "print(Student.student_number) # 2" 254 | ] 255 | }, 256 | { 257 | "cell_type": "code", 258 | "execution_count": 23, 259 | "metadata": { 260 | "collapsed": true 261 | }, 262 | "outputs": [], 263 | "source": [ 264 | "class MasterStudent(Student):\n", 265 | " \"\"\"\n", 266 | " MasterStudent class\n", 267 | " \"\"\"\n", 268 | " def __init__(self, sid, name, score, major):\n", 269 | " \"\"\"\n", 270 | " Student class init method\n", 271 | " \"\"\"\n", 272 | " super().__init__(sid, name, score)\n", 273 | " self.major = major\n", 274 | "\n", 275 | " def print_info(self):\n", 276 | " \"\"\"\n", 277 | " get Student score\n", 278 | " \"\"\"\n", 279 | " super().print_info() # 调用父类方法\n", 280 | " print('and majoring in %s' % self.major)\n", 281 | "\n", 282 | " def change_major(self, major):\n", 283 | " \"\"\"\n", 284 | " change major\n", 285 | " \"\"\"\n", 286 | " super().change_major()\n", 287 | " self.major = major" 288 | ] 289 | }, 290 | { 291 | "cell_type": "code", 292 | "execution_count": 24, 293 | "metadata": { 294 | "scrolled": true 295 | }, 296 | "outputs": [ 297 | { 298 | "name": "stdout", 299 | "output_type": "stream", 300 | "text": [ 301 | "jeffery: 90 and majoring in bio\n" 302 | ] 303 | } 304 | ], 305 | "source": [ 306 | "if __name__ == '__main__':\n", 307 | " ms = MasterStudent('001', 'jeffery', '90', 'bio')\n", 308 | " ms.print_info()" 309 | ] 310 | }, 311 | { 312 | "cell_type": "code", 313 | "execution_count": 36, 314 | "metadata": {}, 315 | "outputs": [ 316 | { 317 | "name": "stdout", 318 | "output_type": "stream", 319 | "text": [ 320 | "1\n", 321 | "1\n", 322 | "2\n", 323 | "3\n", 324 | "5\n", 325 | "8\n", 326 | "13\n" 327 | ] 328 | } 329 | ], 330 | "source": [ 331 | "class Fibs(object):\n", 332 | " def __init__(self, n=20):\n", 333 | " self.a = 0\n", 334 | " self.b = 1\n", 335 | " self.n = n \n", 336 | " def __iter__(self):\n", 337 | " return self\n", 338 | " def __next__(self):\n", 339 | " self.a, self.b = self.b, self.a + self.b\n", 340 | " if self.a > self.n:\n", 341 | " raise StopIteration#处理异常\n", 342 | " return self.a\n", 343 | "\n", 344 | "## 调用\n", 345 | "fibs = Fibs()\n", 346 | "for each in fibs:\n", 347 | " print(each)\n", 348 | "## 输出" 349 | ] 350 | }, 351 | { 352 | "cell_type": "code", 353 | "execution_count": 5, 354 | "metadata": {}, 355 | "outputs": [ 356 | { 357 | "ename": "NameError", 358 | "evalue": "name 'image' is not defined", 359 | "output_type": "error", 360 | "traceback": [ 361 | "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", 362 | "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", 363 | "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[0moutput\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mzeros\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m320\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m320\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m3\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mdtype\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mint\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[0mterm\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mimage\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mnewaxis\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 3\u001b[0m \u001b[0moutput\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mconcatenate\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0moutput\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mterm\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0maxis\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;36m0\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 364 | "\u001b[1;31mNameError\u001b[0m: name 'image' is not defined" 365 | ] 366 | } 367 | ], 368 | "source": [ 369 | "output=np.zeros([1,320,320,3],dtype=int)\n", 370 | "term=image[np.newaxis,:,:,:]\n", 371 | "output=np.concatenate((output,term),axis = 0)" 372 | ] 373 | }, 374 | { 375 | "cell_type": "code", 376 | "execution_count": 31, 377 | "metadata": {}, 378 | "outputs": [ 379 | { 380 | "data": { 381 | "text/plain": [ 382 | "['Demo\\\\0001.png',\n", 383 | " 'Demo\\\\0002.png',\n", 384 | " 'Demo\\\\0003.png',\n", 385 | " 'Demo\\\\0004.png',\n", 386 | " 'Demo\\\\0005.png',\n", 387 | " 'Demo\\\\0006.png',\n", 388 | " 'Demo\\\\0007.png',\n", 389 | " 'Demo\\\\0008.png',\n", 390 | " 'Demo\\\\0009.png',\n", 391 | " 'Demo\\\\0010.png',\n", 392 | " 'Demo\\\\0011.png',\n", 393 | " 'Demo\\\\0012.png',\n", 394 | " 'Demo\\\\0013.png',\n", 395 | " 'Demo\\\\0014.png',\n", 396 | " 'Demo\\\\0015.png',\n", 397 | " 'Demo\\\\0016.png',\n", 398 | " 'Demo\\\\0017.png',\n", 399 | " 'Demo\\\\0018.png',\n", 400 | " 'Demo\\\\0019.png',\n", 401 | " 'Demo\\\\0020.png']" 402 | ] 403 | }, 404 | "execution_count": 31, 405 | "metadata": {}, 406 | "output_type": "execute_result" 407 | } 408 | ], 409 | "source": [ 410 | "#将图片路径写成列表,为后面cv2读入方便\n", 411 | "images_dir = 'Demo' \n", 412 | "ids=sorted(os.listdir(images_dir))\n", 413 | "images_fps=[os.path.join(images_dir, image_id) for image_id in ids]\n" 414 | ] 415 | }, 416 | { 417 | "cell_type": "code", 418 | "execution_count": 51, 419 | "metadata": {}, 420 | "outputs": [ 421 | { 422 | "data": { 423 | "text/plain": [ 424 | "(320, 320, 3)" 425 | ] 426 | }, 427 | "execution_count": 51, 428 | "metadata": {}, 429 | "output_type": "execute_result" 430 | } 431 | ], 432 | "source": [ 433 | "#cv2读入照片,实验用\n", 434 | "image1 = cv2.imread(images_fps[1],1)\n", 435 | "image1 = cv2.cvtColor(image1, cv2.COLOR_BGR2RGB)" 436 | ] 437 | }, 438 | { 439 | "cell_type": "code", 440 | "execution_count": 54, 441 | "metadata": {}, 442 | "outputs": [], 443 | "source": [ 444 | "#批量处理,文件夹内20张照片读成np.array存入3维array‘image’,第一维代表第几张照片\n", 445 | "j=0\n", 446 | "image = np.zeros(shape=(20,320,320))\n", 447 | "for i in images_fps:\n", 448 | " image1 = cv2.imread(i,1)\n", 449 | " image1 = cv2.cvtColor(image1, cv2.COLOR_BGR2RGB)\n", 450 | " image2=image1[:,:,1]\n", 451 | " image2=image2-image2.min()\n", 452 | " image2=image2/image2.max()\n", 453 | " image2[0,:]=0\n", 454 | " image2[image2.shape[0]-1,:]=0\n", 455 | " image2[:,0]=0\n", 456 | " image2[:,image2.shape[1]-1]=0\n", 457 | " image2=np.reshape(image2,(320,320))\n", 458 | " image[j,:,:]=image2\n", 459 | " j=j+1\n" 460 | ] 461 | }, 462 | { 463 | "cell_type": "code", 464 | "execution_count": 55, 465 | "metadata": { 466 | "collapsed": true 467 | }, 468 | "outputs": [], 469 | "source": [ 470 | "cv2.namedWindow(\"Image\",0)\n", 471 | "cv2.imshow('Image',image[0,:,:])\n", 472 | "cv2.waitKey()\n", 473 | "cv2.destroyAllWindows()" 474 | ] 475 | }, 476 | { 477 | "cell_type": "code", 478 | "execution_count": 7, 479 | "metadata": { 480 | "collapsed": true 481 | }, 482 | "outputs": [], 483 | "source": [ 484 | "#cv2显式照片\n", 485 | "cv2.namedWindow(\"Image\",0)\n", 486 | "cv2.imshow('Image',image1)\n", 487 | "cv2.waitKey()\n", 488 | "cv2.destroyAllWindows()" 489 | ] 490 | }, 491 | { 492 | "cell_type": "code", 493 | "execution_count": 8, 494 | "metadata": { 495 | "collapsed": true 496 | }, 497 | "outputs": [], 498 | "source": [ 499 | "#!/usr/bin/env python\n", 500 | "# -*- coding: utf-8 -*-\n", 501 | "# cython: language_level=3\n", 502 | "\"\"\"\n", 503 | "@Time : 2020/4/28 11:13\n", 504 | "@Author : Zhang Qi\n", 505 | "@Email : zhangqi@onlinesign.com.cn\n", 506 | "@File : mat.py\n", 507 | "@Title : MAT算法\n", 508 | "@Description :\n", 509 | " MAT算法用于给定一个字的图片,通过MAT算法返回这个字对应的骨架图片\n", 510 | "\"\"\"\n", 511 | "import numpy as np\n", 512 | "from functools import reduce\n", 513 | "\n", 514 | "\n", 515 | "# =================================================================\n", 516 | "# MAT算法提取骨架\n", 517 | "# =================================================================\n", 518 | "\n", 519 | "\n", 520 | "def __mat_process_first(around_area: np.ndarray) -> bool:\n", 521 | " \"\"\"MAT算法步骤1\n", 522 | "\n", 523 | " 对于相邻像素区域:\n", 524 | " [\n", 525 | " [p9,p2,p3],\n", 526 | " [p8,p1,p4],\n", 527 | " [p7,p6,p5]\n", 528 | " ]\n", 529 | " 包括以下几个部分:\n", 530 | " a. 2 <=非零像素个数 <= 6\n", 531 | " b. 顺时针跳数 = 1\n", 532 | " c. p2 * p4 * p6 = 0\n", 533 | " d. p4 * p6 * p8 = 0\n", 534 | "\n", 535 | " :param around_area: numpy.array, 一个像素的相邻像素,为3*3\n", 536 | " :return: bool,是否满足以上所有条件\n", 537 | " \"\"\"\n", 538 | " result_list = list() # 保存所有步骤是否符合条件\n", 539 | " \"\"\"步骤a\"\"\"\n", 540 | " near_one_count = __near_pix_equal_one_count(around_area)\n", 541 | " result_list.append(2 <= near_one_count <= 6)\n", 542 | " \"\"\"步骤b\"\"\"\n", 543 | " result_list.append(__binary_transform_count(around_area) == 1)\n", 544 | " \"\"\"步骤c\"\"\"\n", 545 | " pix_2 = around_area[0][1]\n", 546 | " pix_4 = around_area[1][2]\n", 547 | " pix_6 = around_area[2][1]\n", 548 | " result_list.append(pix_2 * pix_4 * pix_6 == 0)\n", 549 | " \"\"\"步骤d\"\"\"\n", 550 | " pix_8 = around_area[1][0]\n", 551 | " result_list.append(pix_4 * pix_6 * pix_8 == 0)\n", 552 | "\n", 553 | " return bool(reduce(lambda x, y: x and y, result_list))\n", 554 | "\n", 555 | "\n", 556 | "def __mat_process_second(around_area: np.ndarray) -> bool:\n", 557 | " \"\"\"MAT算法步骤2\n", 558 | " 对于相邻像素区域:\n", 559 | " [\n", 560 | " [p9,p2,p3],\n", 561 | " [p8,p1,p4],\n", 562 | " [p7,p6,p5]\n", 563 | " ]\n", 564 | " 包括以下几个部分:\n", 565 | " a. 2 <=非零像素个数 <= 6\n", 566 | " b. 顺时针跳数 = 1\n", 567 | " c. p2 * p4 * p8 = 0\n", 568 | " d. p2 * p6 * p8 = 0\n", 569 | " :param around_area: numpy.array, 周围的区域\n", 570 | " :return: bool,是否全部子条件\n", 571 | " \"\"\"\n", 572 | " result_list = list() # 保存所有步骤是否符合条件\n", 573 | " \"\"\"步骤a\"\"\"\n", 574 | " near_one_count = __near_pix_equal_one_count(around_area)\n", 575 | " result_list.append(2 <= near_one_count <= 6)\n", 576 | " \"\"\"步骤b\"\"\"\n", 577 | " result_list.append(__binary_transform_count(around_area) == 1)\n", 578 | " \"\"\"步骤c\"\"\"\n", 579 | " pix_2 = around_area[0][1]\n", 580 | " pix_4 = around_area[1][2]\n", 581 | " pix_8 = around_area[1][0]\n", 582 | " pix_6 = around_area[2][1]\n", 583 | " result_list.append(pix_2 * pix_4 * pix_8 == 0)\n", 584 | " \"\"\"步骤d\"\"\"\n", 585 | " result_list.append(pix_2 * pix_6 * pix_8 == 0)\n", 586 | "\n", 587 | " return bool(reduce(lambda x, y: x and y, result_list))\n", 588 | "\n", 589 | "\n", 590 | "def __near_pix_equal_one_count(around_area: np.ndarray) -> int or np.int:\n", 591 | " \"\"\"计算相邻像素中为1的个数(不包括中间点)\n", 592 | "\n", 593 | " 即,对于相邻像素区域:\n", 594 | " [\n", 595 | " [p9,p2,p3],\n", 596 | " [p8,p1,p4],\n", 597 | " [p7,p6,p5]\n", 598 | " ]\n", 599 | " 统计出p1之外所有的1的个数\n", 600 | " :param around_area: numpy.array, 一个像素的相邻像素,为3*3\n", 601 | " :return int,像素为1的个数\n", 602 | " \"\"\"\n", 603 | " temp_around_area = np.copy(around_area)\n", 604 | " temp_around_area[1][1] = 0\n", 605 | " return int(np.sum(temp_around_area, dtype=np.int))\n", 606 | "\n", 607 | "\n", 608 | "def __binary_transform_count(around_area: np.ndarray) -> int or np.int:\n", 609 | " \"\"\"给定一个3*3的二进制图片,获取其顺时针的跳数(从0到1)\n", 610 | "\n", 611 | " 即,对于相邻像素区域:\n", 612 | " [\n", 613 | " [p9,p2,p3],\n", 614 | " [p8,p1,p4],\n", 615 | " [p7,p6,p5]\n", 616 | " ]\n", 617 | " 以p9,p2,p3,p4,p5,p6,p7,p8的顺序访问,如果是0到1,则为一跳\n", 618 | " :param around_area: numpy.array, 一个像素的相邻像素,为3*3\n", 619 | " :return int, 顺时针跳数\n", 620 | " \"\"\"\n", 621 | " def __next_index(current_coor: (int, int)) -> (int, int):\n", 622 | " \"\"\"给定当前位置,返回下一个位置\n", 623 | "\n", 624 | " :param current_coor: (int,int),当前位置\n", 625 | " :return: (int,int), 下一个位置\n", 626 | " \"\"\"\n", 627 | " '''四个方向的下一个位置'''\n", 628 | " right_next = (current_coor[0], current_coor[1] + 1)\n", 629 | " down_next = (current_coor[0] + 1, current_coor[1])\n", 630 | " left_next = (current_coor[0], current_coor[1] - 1)\n", 631 | " up_next = (current_coor[0] - 1, current_coor[1])\n", 632 | "\n", 633 | " \"\"\"按照指定的规则寻找,不报错则表示正确的方向\"\"\"\n", 634 | " next_coordinate_list = [right_next, down_next, left_next, up_next]\n", 635 | " for i, next_coordinate in enumerate(next_coordinate_list):\n", 636 | " try:\n", 637 | " around_area[next_coordinate]\n", 638 | " except IndexError:\n", 639 | " continue\n", 640 | " else:\n", 641 | " '''如果该点已经走过'''\n", 642 | " if is_walked[next_coordinate[0], next_coordinate[1]]:\n", 643 | " continue\n", 644 | " else:\n", 645 | " is_walked[next_coordinate[0], next_coordinate[1]] = True\n", 646 | " return next_coordinate\n", 647 | "\n", 648 | " is_walked = np.full_like(around_area, False) # 用于标识该点是否已经走过\n", 649 | " is_walked[1][1] = True\n", 650 | " transform_count = 0 # 用于记录跳数\n", 651 | " \"\"\"循环对比\"\"\"\n", 652 | " last_pix = around_area[0][0] # 上一个的值\n", 653 | " current_coordinate = (0, 1)\n", 654 | " while current_coordinate != (0, 0):\n", 655 | " current_pix = around_area[current_coordinate[0], current_coordinate[1]]\n", 656 | " if last_pix == 0 and current_pix == 1:\n", 657 | " transform_count += 1\n", 658 | "\n", 659 | " last_pix = current_pix\n", 660 | " current_coordinate = __next_index(current_coordinate)\n", 661 | "\n", 662 | " '''当循环到第一个点时再对比一次'''\n", 663 | " current_pix = around_area[current_coordinate[0], current_coordinate[0]]\n", 664 | " if last_pix == 0 and current_pix == 1:\n", 665 | " transform_count += 1\n", 666 | "\n", 667 | " return transform_count\n", 668 | "\n", 669 | "\n", 670 | "def __remove_pix_by_coordination(img: np.ndarray, points: list):\n", 671 | " \"\"\"给定坐标的list,删除图像上的点(实际就是标记为0)\n", 672 | "\n", 673 | " :param img: numpy.array,图像\n", 674 | " :param points: List[(int,int)]\n", 675 | " \"\"\"\n", 676 | " for single_coordination in points:\n", 677 | " i_row, i_col = single_coordination\n", 678 | " img[i_row][i_col] = 0\n", 679 | "\n", 680 | "\n", 681 | "def __get_remove_points(img: np.ndarray, func) -> [(int, int)]:\n", 682 | " \"\"\"给定图像以及,删除点的规则,返回要删除的点\n", 683 | "\n", 684 | " :param img: numpy.array, 原图像\n", 685 | " :param func: function, 规则,也就是一个函数\n", 686 | " :return: List[(int,int)],坐标的list\n", 687 | " \"\"\"\n", 688 | " remove_points_list = list()\n", 689 | " temp_img = img\n", 690 | " img_iter = np.nditer(temp_img, flags=[\"multi_index\"])\n", 691 | " while not img_iter.finished:\n", 692 | " current_pix = img_iter[0]\n", 693 | " i_row, i_col = img_iter.multi_index\n", 694 | " img_iter.iternext()\n", 695 | " '''如果是背景点则直接跳过'''\n", 696 | " if current_pix != 1:\n", 697 | " continue\n", 698 | "\n", 699 | " \"\"\"如果是前景点\"\"\"\n", 700 | " around_area = temp_img[i_row - 1:i_row + 2, i_col - 1:i_col + 2]\n", 701 | " if func(around_area):\n", 702 | " remove_points_list.append((i_row, i_col))\n", 703 | "\n", 704 | " img_iter.iternext()\n", 705 | " return remove_points_list\n", 706 | "\n", 707 | "\n", 708 | "def get_img_skeleton_by_mat(img: np.ndarray) -> np.ndarray:\n", 709 | " \"\"\"根据字体的图像得到字的骨架\n", 710 | "\n", 711 | " :param img, numpy.array, 原图片\n", 712 | " :raise ValueError\n", 713 | " - 图片不为单通道\n", 714 | " - 图片并未归一化\n", 715 | " - 图片并未标准化\n", 716 | " :return: numpy.array, 骨架图\n", 717 | " \"\"\"\n", 718 | " '''检验图片是否是单通道'''\n", 719 | " if len(img.shape) != 2:\n", 720 | " raise ValueError(\"该图片不是单通道\")\n", 721 | " \"\"\"检验标准化\"\"\"\n", 722 | " if img.max() > 1:\n", 723 | " raise ValueError(\"该图片并未标准化\")\n", 724 | " \"\"\"检验二值化\"\"\"\n", 725 | " if (np.unique(img.flatten()) != (0, 1)).all():\n", 726 | " raise ValueError(\"该函数并未二值化\")\n", 727 | "\n", 728 | " temp_img = img.copy()\n", 729 | " \"\"\"遍历每一个像素点\"\"\"\n", 730 | " is_remove_flag = True # 表示是否继续删除的标志\n", 731 | " i_round = 1 # 记录迭代的轮数\n", 732 | " while is_remove_flag:\n", 733 | " is_remove_flag = False\n", 734 | " print(\"正在执行MAT算法的第{}轮\".format(i_round))\n", 735 | " \"\"\"执行步骤1\"\"\"\n", 736 | " remove_points = __get_remove_points(temp_img, __mat_process_first)\n", 737 | " if len(remove_points) != 0:\n", 738 | " is_remove_flag = True\n", 739 | " __remove_pix_by_coordination(temp_img, remove_points)\n", 740 | "\n", 741 | " \"\"\"执行步骤2\"\"\"\n", 742 | " remove_points = __get_remove_points(temp_img, __mat_process_second)\n", 743 | " if len(remove_points) != 0:\n", 744 | " is_remove_flag = True\n", 745 | " __remove_pix_by_coordination(temp_img, remove_points)\n", 746 | "\n", 747 | " i_round += 1\n", 748 | "\n", 749 | " return temp_img\n" 750 | ] 751 | }, 752 | { 753 | "cell_type": "code", 754 | "execution_count": 26, 755 | "metadata": {}, 756 | "outputs": [ 757 | { 758 | "name": "stdout", 759 | "output_type": "stream", 760 | "text": [ 761 | "1.0\n", 762 | "....\n", 763 | "0.0\n" 764 | ] 765 | } 766 | ], 767 | "source": [ 768 | "#cv2读入照片\n", 769 | "#实验用,不需运行\n", 770 | "image = cv2.imread(images_fps[15],1)\n", 771 | "image = cv2.cvtColor(image1, cv2.COLOR_BGR2RGB)\n", 772 | "#处理成get_img_skeleton_by_mat函数可接受格式\n", 773 | "image4=image1[:,:,1]\n", 774 | "image4=image4-image4.min()\n", 775 | "image4=image4/image4.max()\n", 776 | "image4[0,:]=0\n", 777 | "image4[image4.shape[0]-1,:]=0\n", 778 | "image4[:,0]=0\n", 779 | "image4[:,image4.shape[1]-1]=0\n", 780 | "image5=np.reshape(image4,(320,320))\n", 781 | "print(image4.max())\n", 782 | "print('....')\n", 783 | "print(image4.min())" 784 | ] 785 | }, 786 | { 787 | "cell_type": "code", 788 | "execution_count": 21, 789 | "metadata": {}, 790 | "outputs": [ 791 | { 792 | "data": { 793 | "text/plain": [ 794 | "(320, 320)" 795 | ] 796 | }, 797 | "execution_count": 21, 798 | "metadata": {}, 799 | "output_type": "execute_result" 800 | } 801 | ], 802 | "source": [ 803 | "image4.shape" 804 | ] 805 | }, 806 | { 807 | "cell_type": "code", 808 | "execution_count": 60, 809 | "metadata": {}, 810 | "outputs": [ 811 | { 812 | "name": "stdout", 813 | "output_type": "stream", 814 | "text": [ 815 | "正在执行MAT算法的第1轮\n", 816 | "正在执行MAT算法的第2轮\n", 817 | "正在执行MAT算法的第3轮\n", 818 | "正在执行MAT算法的第4轮\n", 819 | "正在执行MAT算法的第5轮\n", 820 | "正在执行MAT算法的第6轮\n", 821 | "正在执行MAT算法的第1轮\n", 822 | "正在执行MAT算法的第2轮\n", 823 | "正在执行MAT算法的第3轮\n", 824 | "正在执行MAT算法的第4轮\n", 825 | "正在执行MAT算法的第5轮\n", 826 | "正在执行MAT算法的第1轮\n", 827 | "正在执行MAT算法的第2轮\n", 828 | "正在执行MAT算法的第3轮\n", 829 | "正在执行MAT算法的第4轮\n", 830 | "正在执行MAT算法的第5轮\n", 831 | "正在执行MAT算法的第6轮\n", 832 | "正在执行MAT算法的第1轮\n", 833 | "正在执行MAT算法的第2轮\n", 834 | "正在执行MAT算法的第3轮\n", 835 | "正在执行MAT算法的第4轮\n", 836 | "正在执行MAT算法的第5轮\n", 837 | "正在执行MAT算法的第1轮\n", 838 | "正在执行MAT算法的第2轮\n", 839 | "正在执行MAT算法的第3轮\n", 840 | "正在执行MAT算法的第4轮\n", 841 | "正在执行MAT算法的第5轮\n", 842 | "正在执行MAT算法的第1轮\n", 843 | "正在执行MAT算法的第2轮\n", 844 | "正在执行MAT算法的第3轮\n", 845 | "正在执行MAT算法的第4轮\n", 846 | "正在执行MAT算法的第5轮\n", 847 | "正在执行MAT算法的第6轮\n", 848 | "正在执行MAT算法的第7轮\n", 849 | "正在执行MAT算法的第8轮\n", 850 | "正在执行MAT算法的第9轮\n", 851 | "正在执行MAT算法的第10轮\n", 852 | "正在执行MAT算法的第11轮\n", 853 | "正在执行MAT算法的第12轮\n", 854 | "正在执行MAT算法的第13轮\n", 855 | "正在执行MAT算法的第14轮\n", 856 | "正在执行MAT算法的第15轮\n", 857 | "正在执行MAT算法的第16轮\n", 858 | "正在执行MAT算法的第17轮\n", 859 | "正在执行MAT算法的第18轮\n", 860 | "正在执行MAT算法的第19轮\n", 861 | "正在执行MAT算法的第20轮\n", 862 | "正在执行MAT算法的第1轮\n", 863 | "正在执行MAT算法的第2轮\n", 864 | "正在执行MAT算法的第3轮\n", 865 | "正在执行MAT算法的第4轮\n", 866 | "正在执行MAT算法的第5轮\n", 867 | "正在执行MAT算法的第6轮\n", 868 | "正在执行MAT算法的第7轮\n", 869 | "正在执行MAT算法的第8轮\n", 870 | "正在执行MAT算法的第9轮\n", 871 | "正在执行MAT算法的第10轮\n", 872 | "正在执行MAT算法的第11轮\n", 873 | "正在执行MAT算法的第12轮\n", 874 | "正在执行MAT算法的第13轮\n", 875 | "正在执行MAT算法的第1轮\n", 876 | "正在执行MAT算法的第2轮\n", 877 | "正在执行MAT算法的第3轮\n", 878 | "正在执行MAT算法的第4轮\n", 879 | "正在执行MAT算法的第5轮\n", 880 | "正在执行MAT算法的第6轮\n", 881 | "正在执行MAT算法的第7轮\n", 882 | "正在执行MAT算法的第8轮\n", 883 | "正在执行MAT算法的第9轮\n", 884 | "正在执行MAT算法的第10轮\n", 885 | "正在执行MAT算法的第11轮\n", 886 | "正在执行MAT算法的第12轮\n", 887 | "正在执行MAT算法的第13轮\n", 888 | "正在执行MAT算法的第14轮\n", 889 | "正在执行MAT算法的第15轮\n", 890 | "正在执行MAT算法的第16轮\n", 891 | "正在执行MAT算法的第1轮\n", 892 | "正在执行MAT算法的第2轮\n", 893 | "正在执行MAT算法的第3轮\n", 894 | "正在执行MAT算法的第4轮\n", 895 | "正在执行MAT算法的第5轮\n", 896 | "正在执行MAT算法的第6轮\n", 897 | "正在执行MAT算法的第7轮\n", 898 | "正在执行MAT算法的第8轮\n", 899 | "正在执行MAT算法的第9轮\n", 900 | "正在执行MAT算法的第10轮\n", 901 | "正在执行MAT算法的第11轮\n", 902 | "正在执行MAT算法的第12轮\n", 903 | "正在执行MAT算法的第13轮\n", 904 | "正在执行MAT算法的第14轮\n", 905 | "正在执行MAT算法的第15轮\n", 906 | "正在执行MAT算法的第16轮\n", 907 | "正在执行MAT算法的第17轮\n", 908 | "正在执行MAT算法的第1轮\n", 909 | "正在执行MAT算法的第2轮\n", 910 | "正在执行MAT算法的第3轮\n", 911 | "正在执行MAT算法的第4轮\n", 912 | "正在执行MAT算法的第5轮\n", 913 | "正在执行MAT算法的第6轮\n", 914 | "正在执行MAT算法的第7轮\n", 915 | "正在执行MAT算法的第8轮\n", 916 | "正在执行MAT算法的第9轮\n", 917 | "正在执行MAT算法的第10轮\n", 918 | "正在执行MAT算法的第11轮\n", 919 | "正在执行MAT算法的第12轮\n", 920 | "正在执行MAT算法的第13轮\n", 921 | "正在执行MAT算法的第14轮\n", 922 | "正在执行MAT算法的第15轮\n", 923 | "正在执行MAT算法的第16轮\n", 924 | "正在执行MAT算法的第17轮\n", 925 | "正在执行MAT算法的第18轮\n", 926 | "正在执行MAT算法的第1轮\n", 927 | "正在执行MAT算法的第2轮\n", 928 | "正在执行MAT算法的第3轮\n", 929 | "正在执行MAT算法的第4轮\n", 930 | "正在执行MAT算法的第5轮\n", 931 | "正在执行MAT算法的第6轮\n", 932 | "正在执行MAT算法的第7轮\n", 933 | "正在执行MAT算法的第8轮\n", 934 | "正在执行MAT算法的第9轮\n", 935 | "正在执行MAT算法的第1轮\n", 936 | "正在执行MAT算法的第2轮\n", 937 | "正在执行MAT算法的第3轮\n", 938 | "正在执行MAT算法的第4轮\n", 939 | "正在执行MAT算法的第5轮\n", 940 | "正在执行MAT算法的第6轮\n", 941 | "正在执行MAT算法的第7轮\n", 942 | "正在执行MAT算法的第8轮\n", 943 | "正在执行MAT算法的第9轮\n", 944 | "正在执行MAT算法的第1轮\n", 945 | "正在执行MAT算法的第2轮\n", 946 | "正在执行MAT算法的第3轮\n", 947 | "正在执行MAT算法的第4轮\n", 948 | "正在执行MAT算法的第5轮\n", 949 | "正在执行MAT算法的第1轮\n", 950 | "正在执行MAT算法的第2轮\n", 951 | "正在执行MAT算法的第3轮\n", 952 | "正在执行MAT算法的第4轮\n", 953 | "正在执行MAT算法的第5轮\n", 954 | "正在执行MAT算法的第1轮\n", 955 | "正在执行MAT算法的第2轮\n", 956 | "正在执行MAT算法的第3轮\n", 957 | "正在执行MAT算法的第4轮\n", 958 | "正在执行MAT算法的第5轮\n", 959 | "正在执行MAT算法的第6轮\n", 960 | "正在执行MAT算法的第7轮\n", 961 | "正在执行MAT算法的第8轮\n", 962 | "正在执行MAT算法的第9轮\n", 963 | "正在执行MAT算法的第10轮\n", 964 | "正在执行MAT算法的第11轮\n", 965 | "正在执行MAT算法的第12轮\n", 966 | "正在执行MAT算法的第13轮\n", 967 | "正在执行MAT算法的第14轮\n", 968 | "正在执行MAT算法的第15轮\n", 969 | "正在执行MAT算法的第16轮\n", 970 | "正在执行MAT算法的第17轮\n", 971 | "正在执行MAT算法的第18轮\n", 972 | "正在执行MAT算法的第1轮\n", 973 | "正在执行MAT算法的第2轮\n", 974 | "正在执行MAT算法的第3轮\n", 975 | "正在执行MAT算法的第4轮\n", 976 | "正在执行MAT算法的第5轮\n", 977 | "正在执行MAT算法的第6轮\n", 978 | "正在执行MAT算法的第7轮\n", 979 | "正在执行MAT算法的第8轮\n", 980 | "正在执行MAT算法的第9轮\n", 981 | "正在执行MAT算法的第10轮\n", 982 | "正在执行MAT算法的第11轮\n", 983 | "正在执行MAT算法的第12轮\n", 984 | "正在执行MAT算法的第13轮\n", 985 | "正在执行MAT算法的第14轮\n", 986 | "正在执行MAT算法的第15轮\n", 987 | "正在执行MAT算法的第16轮\n", 988 | "正在执行MAT算法的第17轮\n", 989 | "正在执行MAT算法的第18轮\n", 990 | "正在执行MAT算法的第19轮\n", 991 | "正在执行MAT算法的第20轮\n", 992 | "正在执行MAT算法的第21轮\n", 993 | "正在执行MAT算法的第22轮\n", 994 | "正在执行MAT算法的第23轮\n", 995 | "正在执行MAT算法的第24轮\n", 996 | "正在执行MAT算法的第25轮\n", 997 | "正在执行MAT算法的第26轮\n", 998 | "正在执行MAT算法的第27轮\n", 999 | "正在执行MAT算法的第28轮\n", 1000 | "正在执行MAT算法的第29轮\n", 1001 | "正在执行MAT算法的第30轮\n", 1002 | "正在执行MAT算法的第31轮\n", 1003 | "正在执行MAT算法的第32轮\n", 1004 | "正在执行MAT算法的第1轮\n", 1005 | "正在执行MAT算法的第2轮\n", 1006 | "正在执行MAT算法的第3轮\n", 1007 | "正在执行MAT算法的第4轮\n", 1008 | "正在执行MAT算法的第5轮\n", 1009 | "正在执行MAT算法的第6轮\n", 1010 | "正在执行MAT算法的第7轮\n", 1011 | "正在执行MAT算法的第8轮\n", 1012 | "正在执行MAT算法的第9轮\n", 1013 | "正在执行MAT算法的第10轮\n", 1014 | "正在执行MAT算法的第11轮\n", 1015 | "正在执行MAT算法的第12轮\n", 1016 | "正在执行MAT算法的第13轮\n", 1017 | "正在执行MAT算法的第14轮\n", 1018 | "正在执行MAT算法的第15轮\n", 1019 | "正在执行MAT算法的第1轮\n", 1020 | "正在执行MAT算法的第2轮\n", 1021 | "正在执行MAT算法的第3轮\n", 1022 | "正在执行MAT算法的第4轮\n", 1023 | "正在执行MAT算法的第5轮\n", 1024 | "正在执行MAT算法的第6轮\n", 1025 | "正在执行MAT算法的第7轮\n", 1026 | "正在执行MAT算法的第8轮\n", 1027 | "正在执行MAT算法的第9轮\n", 1028 | "正在执行MAT算法的第10轮\n", 1029 | "正在执行MAT算法的第11轮\n", 1030 | "正在执行MAT算法的第12轮\n", 1031 | "正在执行MAT算法的第13轮\n", 1032 | "正在执行MAT算法的第14轮\n", 1033 | "正在执行MAT算法的第1轮\n", 1034 | "正在执行MAT算法的第2轮\n", 1035 | "正在执行MAT算法的第3轮\n", 1036 | "正在执行MAT算法的第4轮\n", 1037 | "正在执行MAT算法的第5轮\n", 1038 | "正在执行MAT算法的第6轮\n", 1039 | "正在执行MAT算法的第7轮\n", 1040 | "正在执行MAT算法的第8轮\n", 1041 | "正在执行MAT算法的第9轮\n", 1042 | "正在执行MAT算法的第10轮\n", 1043 | "正在执行MAT算法的第11轮\n", 1044 | "正在执行MAT算法的第12轮\n", 1045 | "正在执行MAT算法的第13轮\n", 1046 | "正在执行MAT算法的第14轮\n", 1047 | "正在执行MAT算法的第15轮\n", 1048 | "正在执行MAT算法的第16轮\n", 1049 | "正在执行MAT算法的第17轮\n", 1050 | "正在执行MAT算法的第18轮\n", 1051 | "正在执行MAT算法的第19轮\n" 1052 | ] 1053 | } 1054 | ], 1055 | "source": [ 1056 | "skeleton_img = np.zeros(shape=(20,320,320))\n", 1057 | "for i in range (0,19):\n", 1058 | " skeleton_img[i,:,:] = get_img_skeleton_by_mat(image[i,:,:])" 1059 | ] 1060 | }, 1061 | { 1062 | "cell_type": "code", 1063 | "execution_count": 67, 1064 | "metadata": { 1065 | "collapsed": true 1066 | }, 1067 | "outputs": [], 1068 | "source": [ 1069 | "skeleton_img=skeleton_img*255" 1070 | ] 1071 | }, 1072 | { 1073 | "cell_type": "code", 1074 | "execution_count": 68, 1075 | "metadata": {}, 1076 | "outputs": [], 1077 | "source": [ 1078 | "import matplotlib\n", 1079 | "for n in range (0,19):\n", 1080 | " #matplotlib.image.imsave(\"liefeng/%04.d.png\"%(n+1),skeleton_img[n,:,:])\n", 1081 | " cv2.imwrite(\"liefeng/%04.d.png\"%(n+1),skeleton_img[n,:,:])" 1082 | ] 1083 | }, 1084 | { 1085 | "cell_type": "code", 1086 | "execution_count": 27, 1087 | "metadata": { 1088 | "collapsed": true 1089 | }, 1090 | "outputs": [], 1091 | "source": [ 1092 | "cv2.namedWindow(\"Image\",0)\n", 1093 | "cv2.imshow('Image',image4)\n", 1094 | "cv2.waitKey()\n", 1095 | "cv2.destroyAllWindows()" 1096 | ] 1097 | }, 1098 | { 1099 | "cell_type": "code", 1100 | "execution_count": 26, 1101 | "metadata": { 1102 | "collapsed": true, 1103 | "scrolled": true 1104 | }, 1105 | "outputs": [], 1106 | "source": [ 1107 | "test_transform = [\n", 1108 | " albu.Resize(500,500)\n", 1109 | " ]\n", 1110 | "image3=albu.Compose(test_transform)(image=image1)['image']" 1111 | ] 1112 | }, 1113 | { 1114 | "cell_type": "code", 1115 | "execution_count": 27, 1116 | "metadata": {}, 1117 | "outputs": [ 1118 | { 1119 | "data": { 1120 | "image/png": "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\n", 1121 | "text/plain": [ 1122 | "
" 1123 | ] 1124 | }, 1125 | "metadata": {}, 1126 | "output_type": "display_data" 1127 | }, 1128 | { 1129 | "data": { 1130 | "image/png": "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\n", 1131 | "text/plain": [ 1132 | "
" 1133 | ] 1134 | }, 1135 | "metadata": {}, 1136 | "output_type": "display_data" 1137 | } 1138 | ], 1139 | "source": [ 1140 | "#plt显式照片\n", 1141 | "plt.figure(figsize=(2, 2))\n", 1142 | "plt.imshow(image3)\n", 1143 | "plt.show()\n", 1144 | "plt.figure(figsize=(2, 2))\n", 1145 | "plt.imshow(image1)\n", 1146 | "plt.show()" 1147 | ] 1148 | }, 1149 | { 1150 | "cell_type": "code", 1151 | "execution_count": 103, 1152 | "metadata": { 1153 | "collapsed": true 1154 | }, 1155 | "outputs": [], 1156 | "source": [] 1157 | }, 1158 | { 1159 | "cell_type": "code", 1160 | "execution_count": 89, 1161 | "metadata": { 1162 | "collapsed": true 1163 | }, 1164 | "outputs": [], 1165 | "source": [ 1166 | "image5=cv2.imread('gutou.tif',1)\n", 1167 | "image5 = cv2.cvtColor(image5, cv2.COLOR_BGR2RGB)\n", 1168 | "image5=image5[:,:,0]\n", 1169 | "image5=image5/image5.max()" 1170 | ] 1171 | }, 1172 | { 1173 | "cell_type": "code", 1174 | "execution_count": 71, 1175 | "metadata": {}, 1176 | "outputs": [ 1177 | { 1178 | "data": { 1179 | "text/plain": [ 1180 | "(750, 450)" 1181 | ] 1182 | }, 1183 | "execution_count": 71, 1184 | "metadata": {}, 1185 | "output_type": "execute_result" 1186 | } 1187 | ], 1188 | "source": [ 1189 | "image5.shape" 1190 | ] 1191 | }, 1192 | { 1193 | "cell_type": "code", 1194 | "execution_count": 83, 1195 | "metadata": {}, 1196 | "outputs": [ 1197 | { 1198 | "data": { 1199 | "text/plain": [ 1200 | "array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,\n", 1201 | " 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,\n", 1202 | " 26, 27, 28, 29, 30, 31, 32, 33, 34, 420, 421, 422, 423,\n", 1203 | " 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436,\n", 1204 | " 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449],\n", 1205 | " dtype=int64)" 1206 | ] 1207 | }, 1208 | "execution_count": 83, 1209 | "metadata": {}, 1210 | "output_type": "execute_result" 1211 | } 1212 | ], 1213 | "source": [ 1214 | "flag_image5=np.sum(image5,axis=0)\n", 1215 | "image5_zero=np.where(flag_image5 == 0)[0]\n", 1216 | "image5_zero" 1217 | ] 1218 | }, 1219 | { 1220 | "cell_type": "code", 1221 | "execution_count": 90, 1222 | "metadata": { 1223 | "collapsed": true 1224 | }, 1225 | "outputs": [], 1226 | "source": [ 1227 | "image5=image5[0:750,33:421]" 1228 | ] 1229 | }, 1230 | { 1231 | "cell_type": "code", 1232 | "execution_count": 56, 1233 | "metadata": { 1234 | "collapsed": true 1235 | }, 1236 | "outputs": [], 1237 | "source": [ 1238 | "cv2.namedWindow(\"Image\",0)\n", 1239 | "cv2.imshow('Image',image5)\n", 1240 | "cv2.waitKey()\n", 1241 | "cv2.destroyAllWindows()" 1242 | ] 1243 | }, 1244 | { 1245 | "cell_type": "code", 1246 | "execution_count": null, 1247 | "metadata": {}, 1248 | "outputs": [ 1249 | { 1250 | "name": "stdout", 1251 | "output_type": "stream", 1252 | "text": [ 1253 | "正在执行MAT算法的第1轮\n", 1254 | "正在执行MAT算法的第2轮\n", 1255 | "正在执行MAT算法的第3轮\n", 1256 | "正在执行MAT算法的第4轮\n", 1257 | "正在执行MAT算法的第5轮\n", 1258 | "正在执行MAT算法的第6轮\n", 1259 | "正在执行MAT算法的第7轮\n", 1260 | "正在执行MAT算法的第8轮\n", 1261 | "正在执行MAT算法的第9轮\n", 1262 | "正在执行MAT算法的第10轮\n", 1263 | "正在执行MAT算法的第11轮\n", 1264 | "正在执行MAT算法的第12轮\n", 1265 | "正在执行MAT算法的第13轮\n", 1266 | "正在执行MAT算法的第14轮\n", 1267 | "正在执行MAT算法的第20轮\n", 1268 | "正在执行MAT算法的第21轮\n", 1269 | "正在执行MAT算法的第22轮\n", 1270 | "正在执行MAT算法的第23轮\n", 1271 | "正在执行MAT算法的第24轮\n", 1272 | "正在执行MAT算法的第25轮\n", 1273 | "正在执行MAT算法的第26轮\n", 1274 | "正在执行MAT算法的第27轮\n", 1275 | "正在执行MAT算法的第28轮\n", 1276 | "正在执行MAT算法的第29轮\n", 1277 | "正在执行MAT算法的第30轮\n", 1278 | "正在执行MAT算法的第31轮\n", 1279 | "正在执行MAT算法的第32轮\n", 1280 | "正在执行MAT算法的第33轮\n", 1281 | "正在执行MAT算法的第34轮\n", 1282 | "正在执行MAT算法的第35轮\n", 1283 | "正在执行MAT算法的第36轮\n", 1284 | "正在执行MAT算法的第37轮\n", 1285 | "正在执行MAT算法的第38轮\n", 1286 | "正在执行MAT算法的第39轮\n", 1287 | "正在执行MAT算法的第40轮\n", 1288 | "正在执行MAT算法的第41轮\n", 1289 | "正在执行MAT算法的第42轮\n", 1290 | "正在执行MAT算法的第43轮\n", 1291 | "正在执行MAT算法的第44轮\n", 1292 | "正在执行MAT算法的第45轮\n", 1293 | "正在执行MAT算法的第46轮\n", 1294 | "正在执行MAT算法的第47轮\n", 1295 | "正在执行MAT算法的第48轮\n", 1296 | "正在执行MAT算法的第49轮\n", 1297 | "正在执行MAT算法的第50轮\n", 1298 | "正在执行MAT算法的第51轮\n", 1299 | "正在执行MAT算法的第52轮\n", 1300 | "正在执行MAT算法的第53轮\n", 1301 | "正在执行MAT算法的第54轮\n", 1302 | "正在执行MAT算法的第55轮\n", 1303 | "正在执行MAT算法的第56轮\n", 1304 | "正在执行MAT算法的第57轮\n", 1305 | "正在执行MAT算法的第58轮\n" 1306 | ] 1307 | } 1308 | ], 1309 | "source": [ 1310 | "skeleton_img = get_img_skeleton_by_mat(image5)#图片边界不能有对象,必须是黑的" 1311 | ] 1312 | }, 1313 | { 1314 | "cell_type": "code", 1315 | "execution_count": 30, 1316 | "metadata": { 1317 | "collapsed": true 1318 | }, 1319 | "outputs": [], 1320 | "source": [ 1321 | "cv2.namedWindow(\"Image\",0)\n", 1322 | "cv2.imshow('Image',skeleton_img)\n", 1323 | "cv2.waitKey()\n", 1324 | "cv2.destroyAllWindows()" 1325 | ] 1326 | } 1327 | ], 1328 | "metadata": { 1329 | "kernelspec": { 1330 | "display_name": "Python [conda env:pytorch2]", 1331 | "language": "python", 1332 | "name": "conda-env-pytorch2-py" 1333 | }, 1334 | "language_info": { 1335 | "codemirror_mode": { 1336 | "name": "ipython", 1337 | "version": 3 1338 | }, 1339 | "file_extension": ".py", 1340 | "mimetype": "text/x-python", 1341 | "name": "python", 1342 | "nbconvert_exporter": "python", 1343 | "pygments_lexer": "ipython3", 1344 | "version": "3.6.2" 1345 | } 1346 | }, 1347 | "nbformat": 4, 1348 | "nbformat_minor": 2 1349 | } 1350 | -------------------------------------------------------------------------------- /test.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "#!pip install segmentation_models_pytorch # Install dependencies\n", 12 | "#!pip install timm\n", 13 | "#!pip install -U git+https://github.com/albu/albumentations --no-cache-dir\n", 14 | "#!pip install -U git+https://github.com/albumentations-team/albumentations\n", 15 | "#!pip install albumentations\n", 16 | "#!pip install segmentation_models_pytorch\n", 17 | "import segmentation_models_pytorch as smp\n", 18 | "import os\n", 19 | "import numpy as np\n", 20 | "import cv2\n", 21 | "import matplotlib.pyplot as plt\n", 22 | "import albumentations as albu\n", 23 | "import torch\n", 24 | "import numpy as np\n", 25 | "from torch.utils.data import DataLoader\n", 26 | "from torch.utils.data import Dataset as BaseDataset\n", 27 | "os.environ['CUDA_VISIBLE_DEVICES'] = '0'" 28 | ] 29 | }, 30 | { 31 | "cell_type": "code", 32 | "execution_count": 22, 33 | "metadata": { 34 | "collapsed": true 35 | }, 36 | "outputs": [], 37 | "source": [ 38 | "DATA_DIR = './'\n", 39 | "x_test_dir = 'test1/image' # Note: put the dataset on the current path.\n", 40 | "y_test_dir = 'test1/label/' # You can modify it to test on the 2-80 Additional Original Images" 41 | ] 42 | }, 43 | { 44 | "cell_type": "code", 45 | "execution_count": 23, 46 | "metadata": {}, 47 | "outputs": [ 48 | { 49 | "name": "stderr", 50 | "output_type": "stream", 51 | "text": [ 52 | "D:\\Users\\PC\\Anaconda3\\envs\\pytorch2\\lib\\site-packages\\torch\\serialization.py:656: SourceChangeWarning: source code of class 'segmentation_models_pytorch.fpn.model.FPN' has changed. you can retrieve the original source code by accessing the object's source attribute or set `torch.nn.Module.dump_patches = True` and use the patch tool to revert the changes.\n", 53 | " warnings.warn(msg, SourceChangeWarning)\n", 54 | "D:\\Users\\PC\\Anaconda3\\envs\\pytorch2\\lib\\site-packages\\torch\\serialization.py:656: SourceChangeWarning: source code of class 'segmentation_models_pytorch.encoders.senet.SENetEncoder' has changed. you can retrieve the original source code by accessing the object's source attribute or set `torch.nn.Module.dump_patches = True` and use the patch tool to revert the changes.\n", 55 | " warnings.warn(msg, SourceChangeWarning)\n", 56 | "D:\\Users\\PC\\Anaconda3\\envs\\pytorch2\\lib\\site-packages\\torch\\serialization.py:656: SourceChangeWarning: source code of class 'torch.nn.modules.container.Sequential' has changed. you can retrieve the original source code by accessing the object's source attribute or set `torch.nn.Module.dump_patches = True` and use the patch tool to revert the changes.\n", 57 | " warnings.warn(msg, SourceChangeWarning)\n", 58 | "D:\\Users\\PC\\Anaconda3\\envs\\pytorch2\\lib\\site-packages\\torch\\serialization.py:656: SourceChangeWarning: source code of class 'torch.nn.modules.conv.Conv2d' has changed. you can retrieve the original source code by accessing the object's source attribute or set `torch.nn.Module.dump_patches = True` and use the patch tool to revert the changes.\n", 59 | " warnings.warn(msg, SourceChangeWarning)\n", 60 | "D:\\Users\\PC\\Anaconda3\\envs\\pytorch2\\lib\\site-packages\\torch\\serialization.py:656: SourceChangeWarning: source code of class 'torch.nn.modules.batchnorm.BatchNorm2d' has changed. you can retrieve the original source code by accessing the object's source attribute or set `torch.nn.Module.dump_patches = True` and use the patch tool to revert the changes.\n", 61 | " warnings.warn(msg, SourceChangeWarning)\n", 62 | "D:\\Users\\PC\\Anaconda3\\envs\\pytorch2\\lib\\site-packages\\torch\\serialization.py:656: SourceChangeWarning: source code of class 'torch.nn.modules.activation.ReLU' has changed. you can retrieve the original source code by accessing the object's source attribute or set `torch.nn.Module.dump_patches = True` and use the patch tool to revert the changes.\n", 63 | " warnings.warn(msg, SourceChangeWarning)\n", 64 | "D:\\Users\\PC\\Anaconda3\\envs\\pytorch2\\lib\\site-packages\\torch\\serialization.py:656: SourceChangeWarning: source code of class 'torch.nn.modules.pooling.MaxPool2d' has changed. you can retrieve the original source code by accessing the object's source attribute or set `torch.nn.Module.dump_patches = True` and use the patch tool to revert the changes.\n", 65 | " warnings.warn(msg, SourceChangeWarning)\n", 66 | "D:\\Users\\PC\\Anaconda3\\envs\\pytorch2\\lib\\site-packages\\torch\\serialization.py:656: SourceChangeWarning: source code of class 'torch.nn.modules.pooling.AdaptiveAvgPool2d' has changed. you can retrieve the original source code by accessing the object's source attribute or set `torch.nn.Module.dump_patches = True` and use the patch tool to revert the changes.\n", 67 | " warnings.warn(msg, SourceChangeWarning)\n", 68 | "D:\\Users\\PC\\Anaconda3\\envs\\pytorch2\\lib\\site-packages\\torch\\serialization.py:656: SourceChangeWarning: source code of class 'torch.nn.modules.activation.Sigmoid' has changed. you can retrieve the original source code by accessing the object's source attribute or set `torch.nn.Module.dump_patches = True` and use the patch tool to revert the changes.\n", 69 | " warnings.warn(msg, SourceChangeWarning)\n", 70 | "D:\\Users\\PC\\Anaconda3\\envs\\pytorch2\\lib\\site-packages\\torch\\serialization.py:656: SourceChangeWarning: source code of class 'torch.nn.modules.container.ModuleList' has changed. you can retrieve the original source code by accessing the object's source attribute or set `torch.nn.Module.dump_patches = True` and use the patch tool to revert the changes.\n", 71 | " warnings.warn(msg, SourceChangeWarning)\n", 72 | "D:\\Users\\PC\\Anaconda3\\envs\\pytorch2\\lib\\site-packages\\torch\\serialization.py:656: SourceChangeWarning: source code of class 'torch.nn.modules.normalization.GroupNorm' has changed. you can retrieve the original source code by accessing the object's source attribute or set `torch.nn.Module.dump_patches = True` and use the patch tool to revert the changes.\n", 73 | " warnings.warn(msg, SourceChangeWarning)\n", 74 | "D:\\Users\\PC\\Anaconda3\\envs\\pytorch2\\lib\\site-packages\\torch\\serialization.py:656: SourceChangeWarning: source code of class 'torch.nn.modules.dropout.Dropout2d' has changed. you can retrieve the original source code by accessing the object's source attribute or set `torch.nn.Module.dump_patches = True` and use the patch tool to revert the changes.\n", 75 | " warnings.warn(msg, SourceChangeWarning)\n", 76 | "D:\\Users\\PC\\Anaconda3\\envs\\pytorch2\\lib\\site-packages\\torch\\serialization.py:656: SourceChangeWarning: source code of class 'torch.nn.modules.upsampling.UpsamplingBilinear2d' has changed. you can retrieve the original source code by accessing the object's source attribute or set `torch.nn.Module.dump_patches = True` and use the patch tool to revert the changes.\n", 77 | " warnings.warn(msg, SourceChangeWarning)\n", 78 | "D:\\Users\\PC\\Anaconda3\\envs\\pytorch2\\lib\\site-packages\\torch\\serialization.py:656: SourceChangeWarning: source code of class 'segmentation_models_pytorch.base.modules.Activation' has changed. you can retrieve the original source code by accessing the object's source attribute or set `torch.nn.Module.dump_patches = True` and use the patch tool to revert the changes.\n", 79 | " warnings.warn(msg, SourceChangeWarning)\n" 80 | ] 81 | } 82 | ], 83 | "source": [ 84 | "DEVICE = 'cuda'\n", 85 | "CLASSES = ['crack']\n", 86 | "ENCODER = 'se_resnext50_32x4d'\n", 87 | "ENCODER_WEIGHTS = 'imagenet'\n", 88 | "CLASSES = ['crack']\n", 89 | "ACTIVATION = 'sigmoid' # could be None for logits or 'softmax2d' for multicalss segmentation\n", 90 | "# create segmentation model with pretrained encoder\n", 91 | "preprocessing_fn = smp.encoders.get_preprocessing_fn(ENCODER, ENCODER_WEIGHTS)\n", 92 | "fpn = torch.load('fpn.pth',map_location=DEVICE).to(DEVICE)" 93 | ] 94 | }, 95 | { 96 | "cell_type": "code", 97 | "execution_count": 4, 98 | "metadata": { 99 | "collapsed": true 100 | }, 101 | "outputs": [], 102 | "source": [ 103 | "# from PIL import Image\n", 104 | "import numpy as np\n", 105 | "import matplotlib.pyplot as plt\n", 106 | "import cv2\n", 107 | "# get the imread result from test set((3864, 5152, 3)or(3264, 4928, 3) numpy), return numpy of (98,3,480,640)or(145,3,480,640)\n", 108 | "def testdataprocessing(img):\n", 109 | " h,w,c = img.shape\n", 110 | " #padding the images with zeros\n", 111 | " if h == 2448:\n", 112 | " img = cv2.copyMakeBorder(img , 216, 216, 288 , 288, cv2.BORDER_CONSTANT, value=0)\n", 113 | " ##(6*480=2880,6*640=3840)\n", 114 | " elif h == 3024:\n", 115 | " img = cv2.copyMakeBorder(img,168,168,224 , 224, cv2.BORDER_CONSTANT, value=0)\n", 116 | " output = np.zeros([1,480,640,3], dtype=int)\n", 117 | " #(7*480=3360,7*640=4480)\n", 118 | " h,w,c = img.shape\n", 119 | " #set the stride in colomns/rows is 480/640\n", 120 | " stride_h = 480\n", 121 | " stride_w = 640\n", 122 | " if h == 2880:\n", 123 | " column = int(h/480)\n", 124 | " row = int(w/640)\n", 125 | " for i in range(row):\n", 126 | " for j in range(column):\n", 127 | " term = np.zeros([480,640,3], dtype=int)\n", 128 | " term = img[j*stride_h:j*stride_h + stride_h, i*stride_w : i*stride_w+stride_w,:].copy() \n", 129 | " term = term[np.newaxis,:,:,:]\n", 130 | " output = np.concatenate((output,term),axis = 0)\n", 131 | " output = np.delete(output,0,axis = 0)\n", 132 | " #get the center part of raw images and split again\n", 133 | " img_seg = img[240:2640,320:3520,:].copy()\n", 134 | " for i in range(row-1):\n", 135 | " for j in range(column-1):\n", 136 | " term = np.zeros([480,640,3], dtype=int)\n", 137 | " term = img_seg[j*stride_h:j*stride_h + stride_h, i*stride_w : i*stride_w+stride_w,:].copy() \n", 138 | " term = term[np.newaxis,:,:,:]\n", 139 | " output = np.concatenate((output,term),axis = 0)\n", 140 | "\n", 141 | " if h == 3360:\n", 142 | " column = int(h/480)\n", 143 | " row = int(w/640)\n", 144 | " for i in range(row):\n", 145 | " for j in range(column):\n", 146 | " term = np.zeros([480,640,3], dtype=int)\n", 147 | " term = img[j*stride_h:j*stride_h + stride_h, i*stride_w : i*stride_w+stride_w,:].copy() \n", 148 | " term = term[np.newaxis,:,:,:]\n", 149 | " output = np.concatenate((output,term),axis = 0)\n", 150 | " output = np.delete(output,0,axis = 0)\n", 151 | " #get the center part of raw images and split again\n", 152 | " img_seg = img[240:3120,320:4160,:].copy()\n", 153 | " for i in range(row-1):\n", 154 | " for j in range(column-1):\n", 155 | " term = np.zeros([480,640,3], dtype=int)\n", 156 | " term = img_seg[j*stride_h:j*stride_h + stride_h, i*stride_w : i*stride_w+stride_w,:].copy() \n", 157 | " term = term[np.newaxis,:,:,:]\n", 158 | " output = np.concatenate((output,term),axis = 0)\n", 159 | " return output\n", 160 | "\n", 161 | "#trainsofrm the numpy of (98,480,640)/(145,480,640)back into (3864,5152)or(3264,4928)\n", 162 | "def visualizaion(output):\n", 163 | " n,stride_h,stride_w = output.shape \n", 164 | " if n == 61:\n", 165 | " count = 0\n", 166 | " #combine the firt part of predition\n", 167 | " mask_1 = np.zeros([2880,3840], dtype=int)\n", 168 | " for i in range (6):\n", 169 | " for j in range(6):\n", 170 | " mask_1[j*stride_h:j*stride_h + stride_h, i*stride_w : i*stride_w+stride_w] = output[count,:,:].copy() \n", 171 | " count += 1\n", 172 | " mask_2 = np.zeros([2400,3200], dtype=int) \n", 173 | " #combine the second part of prediction\n", 174 | " for i in range (5):\n", 175 | " for j in range(5):\n", 176 | " mask_2[j*stride_h:j*stride_h + stride_h, i*stride_w : i*stride_w+stride_w] = output[count,:,:].copy() \n", 177 | " count += 1 \n", 178 | " #sum the mask1 and mask2 in pixel level\n", 179 | " mask_3 = mask_1[240:2640,320:3520].copy() + mask_2[:,:].copy()\n", 180 | " mask_3 = mask_3*0.5\n", 181 | " prediction = mask_1.copy()\n", 182 | " prediction[240:2640,320:3520] = mask_3[:,:]\n", 183 | " p = prediction[216:2664,288:3552].copy() \n", 184 | " if n == 85:\n", 185 | " count = 0\n", 186 | " #combine the first part of prediction\n", 187 | " mask_1 = np.zeros([3360,4480], dtype=int)\n", 188 | " for i in range (7):\n", 189 | " for j in range(7):\n", 190 | " mask_1[j*stride_h:j*stride_h + stride_h, i*stride_w : i*stride_w+stride_w] = output[count,:,:].copy() \n", 191 | " count += 1\n", 192 | " mask_2 = np.zeros([2880,3840], dtype=int) \n", 193 | " #combine the second part of prediction\n", 194 | " for i in range (6):\n", 195 | " for j in range(6):\n", 196 | " mask_2[j*stride_h:j*stride_h + stride_h, i*stride_w : i*stride_w+stride_w] = output[count,:,:].copy() \n", 197 | " count += 1 \n", 198 | " #sum the mask1 and mask2 in pixel level\n", 199 | " mask_3 = mask_1[240:3120,320:4160].copy() + mask_2[:,:].copy()\n", 200 | " mask_3 = mask_3*0.5\n", 201 | " prediction = mask_1.copy()\n", 202 | " prediction[240:3120,320:4160] = mask_3[:,:]\n", 203 | " p = prediction[168:3192,224:4256].copy() \n", 204 | " return p" 205 | ] 206 | }, 207 | { 208 | "cell_type": "code", 209 | "execution_count": 24, 210 | "metadata": { 211 | "collapsed": true 212 | }, 213 | "outputs": [], 214 | "source": [ 215 | "from PIL import Image\n", 216 | "import numpy as np\n", 217 | "import matplotlib.pyplot as plt\n", 218 | "import cv2\n", 219 | "# get the imread result from test set((3864, 5152, 3)or(3264, 4928, 3) numpy), return numpy of (98,3,480,640)or(145,3,480,640)\n", 220 | "def testdataprocessing(img):\n", 221 | " output = np.zeros([1,320,320,3], dtype=int)\n", 222 | " term = img[np.newaxis,:,:,:]\n", 223 | " output = np.concatenate((output,term),axis = 0)\n", 224 | " print(output.shape)\n", 225 | " return output\n" 226 | ] 227 | }, 228 | { 229 | "cell_type": "code", 230 | "execution_count": 25, 231 | "metadata": { 232 | "collapsed": true 233 | }, 234 | "outputs": [], 235 | "source": [ 236 | "def visualizaion(output):\n", 237 | " n,stride_h,stride_w = output.shape \n", 238 | " \n", 239 | " mask = np.zeros([320,320], dtype=int)\n", 240 | " mask[:,:] = output[1,:,:].copy() \n", 241 | " return mask" 242 | ] 243 | }, 244 | { 245 | "cell_type": "code", 246 | "execution_count": 26, 247 | "metadata": { 248 | "collapsed": true 249 | }, 250 | "outputs": [], 251 | "source": [ 252 | "# Define the dataset\n", 253 | "class Dataset(BaseDataset):\n", 254 | " \"\"\"\n", 255 | " Args:\n", 256 | " images_dir (str): path to images folder\n", 257 | " masks_dir (str): path to segmentation masks folder\n", 258 | " class_values (list): values of classes to extract from segmentation mask\n", 259 | " augmentation (albumentations.Compose): data transfromation pipeline \n", 260 | " (e.g. flip, scale, etc.)\n", 261 | " preprocessing (albumentations.Compose): data preprocessing \n", 262 | " (e.g. noralization, shape manipulation, etc.)\n", 263 | " Note: we don't need mask when testing.\n", 264 | " \n", 265 | " \"\"\"\n", 266 | " \n", 267 | " CLASSES = ['crack']\n", 268 | " \n", 269 | " def __init__(\n", 270 | " self, \n", 271 | " images_dir, \n", 272 | " classes=None, \n", 273 | " augmentation=None, \n", 274 | " preprocessing=None,\n", 275 | " ):\n", 276 | " self.ids = sorted(os.listdir(images_dir))\n", 277 | " #将image文件夹下的所有照片名称创建为一个列表并且顺序排列['001.png','002.png'.....]\n", 278 | " self.images_fps = [os.path.join(images_dir, image_id) for image_id in self.ids]\n", 279 | " #将所有照片路径创建为列表['test1/image\\\\0001.png','test1/image\\\\0002.png'...]\n", 280 | " \n", 281 | " # convert str names to class values on masks名称变成值?\n", 282 | " self.class_values = [self.CLASSES.index(cls.lower()) for cls in classes]\n", 283 | " \n", 284 | " self.augmentation = augmentation\n", 285 | " self.preprocessing = preprocessing\n", 286 | " \n", 287 | " def __getitem__(self, i):\n", 288 | " \n", 289 | " # read data\n", 290 | " image = cv2.imread(self.images_fps[i],1)\n", 291 | " #1加载彩色,0加载灰度,-1还读入alpha通道代表透明度\n", 292 | " image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n", 293 | " #opencv默认通道是bgr,这是早期留下来的问题。因此将bgr转换为rgb\n", 294 | " # apply augmentations\n", 295 | " if self.augmentation:\n", 296 | " sample = self.augmentation(image=image)\n", 297 | " image = sample['image']\n", 298 | " if self.preprocessing:\n", 299 | " sample = self.preprocessing(image=image)\n", 300 | " image = sample['image']\n", 301 | " image = testdataprocessing(image.transpose(1,2,0))\n", 302 | " image = image.transpose(0,3,1,2)\n", 303 | " return image\n", 304 | " \n", 305 | " def __len__(self):\n", 306 | " return len(self.ids)\n", 307 | " #暂时不知道什么用" 308 | ] 309 | }, 310 | { 311 | "cell_type": "code", 312 | "execution_count": 27, 313 | "metadata": {}, 314 | "outputs": [], 315 | "source": [ 316 | "# create test dataset\n", 317 | "def get_validation_augmentation():\n", 318 | " \"\"\"You can put some augmentations on here\"\"\"\n", 319 | " #可以加入不同的操作,只需放在test_transform列表里。Resize可以不改变照片内容,改变图片像素尺寸\n", 320 | " test_transform = [\n", 321 | " albu.Resize(320,320),\n", 322 | " ]\n", 323 | " return albu.Compose(test_transform)\n", 324 | " #就是将所有操作打包起来,对对象操作时:image3=albu.Compose(test_transform)(image=image_name)['image']\n", 325 | "def to_tensor(x, **kwargs):\n", 326 | " return x.transpose(2, 0, 1).astype('float32')\n", 327 | "def get_preprocessing(preprocessing_fn):\n", 328 | " \"\"\"Construct preprocessing transform\n", 329 | " \n", 330 | " Args:\n", 331 | " preprocessing_fn (callbale): data normalization function \n", 332 | " (can be specific for each pretrained neural network)\n", 333 | " Return:\n", 334 | " transform: albumentations.Compose\n", 335 | " \n", 336 | " \"\"\"\n", 337 | " \n", 338 | " _transform = [\n", 339 | " albu.Lambda(image=preprocessing_fn),\n", 340 | " albu.Lambda(image=to_tensor),\n", 341 | " ]\n", 342 | " return albu.Compose(_transform)\n", 343 | " \n", 344 | "test_dataset = Dataset(\n", 345 | " x_test_dir, \n", 346 | " augmentation=None, # for test, we just set augmentation to None\n", 347 | " preprocessing=get_preprocessing(preprocessing_fn),\n", 348 | " classes=CLASSES,\n", 349 | ")\n" 350 | ] 351 | }, 352 | { 353 | "cell_type": "code", 354 | "execution_count": 28, 355 | "metadata": { 356 | "scrolled": true 357 | }, 358 | "outputs": [ 359 | { 360 | "name": "stdout", 361 | "output_type": "stream", 362 | "text": [ 363 | "0\n", 364 | "(2, 320, 320, 3)\n", 365 | "1\n", 366 | "(2, 320, 320, 3)\n", 367 | "2\n", 368 | "(2, 320, 320, 3)\n", 369 | "3\n", 370 | "(2, 320, 320, 3)\n", 371 | "4\n", 372 | "(2, 320, 320, 3)\n" 373 | ] 374 | } 375 | ], 376 | "source": [ 377 | "import matplotlib\n", 378 | "pre_1 = []\n", 379 | "os.system('mkdir Demo')\n", 380 | "# output mask\n", 381 | "for n in range(len(test_dataset)):\n", 382 | " print(n)\n", 383 | " image = test_dataset[n]\n", 384 | " x_tensor = torch.FloatTensor(image).to(DEVICE)\n", 385 | " shape = x_tensor.shape[0]//3 # reduce memory on GPU\n", 386 | " pr_mask = []\n", 387 | " with torch.no_grad():\n", 388 | " mask = fpn.predict(x_tensor).squeeze().detach().cpu().numpy().round()\n", 389 | " pr_mask.append(mask)\n", 390 | "# mask = fpn.predict(x_tensor[shape:shape*2]).squeeze().detach().cpu().numpy().round()\n", 391 | "# pr_mask.append(mask)\n", 392 | "# mask = fpn.predict(x_tensor[shape*2:]).squeeze().detach().cpu().numpy().round()\n", 393 | "# pr_mask.append(mask)\n", 394 | " pr_mask = np.concatenate(np.array(pr_mask),axis=0) # concatenate three pieces\n", 395 | " pr_mask= visualizaion(pr_mask)\n", 396 | " pr_mask[pr_mask > 0]=1\n", 397 | " pre_1.append(pr_mask)\n", 398 | " matplotlib.image.imsave(\"Demo2/%04.d.png\"%(n+1), pr_mask)\n" 399 | ] 400 | }, 401 | { 402 | "cell_type": "code", 403 | "execution_count": 10, 404 | "metadata": { 405 | "scrolled": true 406 | }, 407 | "outputs": [ 408 | { 409 | "name": "stdout", 410 | "output_type": "stream", 411 | "text": [ 412 | "1 : 0.5852\n", 413 | "2 : 0.5167\n", 414 | "3 : 0.5706\n", 415 | "4 : 0.6068\n", 416 | "5 : 0.6344\n", 417 | "6 : 0.8475\n", 418 | "7 : 0.8503\n", 419 | "8 : 0.8307\n", 420 | "9 : 0.8206\n", 421 | "10 : 0.8184\n", 422 | "11 : 0.7651\n", 423 | "12 : 0.8063\n", 424 | "13 : 0.7736\n", 425 | "14 : 0.6648\n", 426 | "15 : 0.8392\n", 427 | "16 : 0.8998\n", 428 | "17 : 0.8346\n", 429 | "18 : 0.7713\n", 430 | "19 : 0.8126\n", 431 | "20 : 0.8326\n", 432 | "Final miou: 0.7540582825979366\n" 433 | ] 434 | } 435 | ], 436 | "source": [ 437 | "# calculate iou\n", 438 | "data = []\n", 439 | "for j,i in enumerate(sorted(os.listdir(x_test_dir))):\n", 440 | " mask_1 = cv2.imread(\"Demo/\"+i,0)\n", 441 | " mask_1[mask_1==30]=0\n", 442 | " mask_1[mask_1==215]=1\n", 443 | " mask_2 = cv2.imread(y_test_dir+i, 0)\n", 444 | " mask_2[mask_2>0]=1\n", 445 | " mask_3 = mask_1 & mask_2\n", 446 | " mask_2[mask_1>0]=1\n", 447 | " iou = mask_3.sum()/mask_2.sum()\n", 448 | " print(str(j+1),':',\"%.4f\" % (iou))\n", 449 | " data.append(iou)\n", 450 | "print(\"Final miou:\", np.mean(data))" 451 | ] 452 | }, 453 | { 454 | "cell_type": "code", 455 | "execution_count": 11, 456 | "metadata": { 457 | "collapsed": true 458 | }, 459 | "outputs": [], 460 | "source": [ 461 | "from torchsummary import summary" 462 | ] 463 | }, 464 | { 465 | "cell_type": "code", 466 | "execution_count": 12, 467 | "metadata": {}, 468 | "outputs": [ 469 | { 470 | "ename": "TypeError", 471 | "evalue": "'int' object is not callable", 472 | "output_type": "error", 473 | "traceback": [ 474 | "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", 475 | "\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)", 476 | "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0msummary\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mfpn\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m3\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m320\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m320\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", 477 | "\u001b[1;32mD:\\Users\\PC\\Anaconda3\\envs\\pytorch2\\lib\\site-packages\\torchsummary\\torchsummary.py\u001b[0m in \u001b[0;36msummary\u001b[1;34m(model, input_size, batch_size, device)\u001b[0m\n\u001b[0;32m 77\u001b[0m \u001b[1;31m# make a forward pass\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 78\u001b[0m \u001b[1;31m# print(x.shape)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 79\u001b[1;33m \u001b[0mmodel\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0mx\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 80\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 81\u001b[0m \u001b[1;31m# remove these hooks\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 478 | "\u001b[1;32mD:\\Users\\PC\\Anaconda3\\envs\\pytorch2\\lib\\site-packages\\torch\\nn\\modules\\module.py\u001b[0m in \u001b[0;36m_call_impl\u001b[1;34m(self, *input, **kwargs)\u001b[0m\n\u001b[0;32m 887\u001b[0m \u001b[0mresult\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_slow_forward\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0minput\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 888\u001b[0m \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 889\u001b[1;33m \u001b[0mresult\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mforward\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0minput\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 890\u001b[0m for hook in itertools.chain(\n\u001b[0;32m 891\u001b[0m \u001b[0m_global_forward_hooks\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mvalues\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 479 | "\u001b[1;32mD:\\Users\\PC\\Anaconda3\\envs\\pytorch2\\lib\\site-packages\\segmentation_models_pytorch\\base\\model.py\u001b[0m in \u001b[0;36mforward\u001b[1;34m(self, x)\u001b[0m\n\u001b[0;32m 14\u001b[0m \u001b[1;34m\"\"\"Sequentially pass `x` trough model`s encoder, decoder and heads\"\"\"\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 15\u001b[0m \u001b[0mfeatures\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mencoder\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mx\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 16\u001b[1;33m \u001b[0mdecoder_output\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdecoder\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0mfeatures\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 17\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 18\u001b[0m \u001b[0mmasks\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msegmentation_head\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mdecoder_output\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 480 | "\u001b[1;32mD:\\Users\\PC\\Anaconda3\\envs\\pytorch2\\lib\\site-packages\\torch\\nn\\modules\\module.py\u001b[0m in \u001b[0;36m_call_impl\u001b[1;34m(self, *input, **kwargs)\u001b[0m\n\u001b[0;32m 887\u001b[0m \u001b[0mresult\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_slow_forward\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0minput\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 888\u001b[0m \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 889\u001b[1;33m \u001b[0mresult\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mforward\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0minput\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 890\u001b[0m for hook in itertools.chain(\n\u001b[0;32m 891\u001b[0m \u001b[0m_global_forward_hooks\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mvalues\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 481 | "\u001b[1;32mD:\\Users\\PC\\Anaconda3\\envs\\pytorch2\\lib\\site-packages\\segmentation_models_pytorch\\fpn\\decoder.py\u001b[0m in \u001b[0;36mforward\u001b[1;34m(self, *features)\u001b[0m\n\u001b[0;32m 114\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 115\u001b[0m \u001b[0mfeature_pyramid\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m[\u001b[0m\u001b[0mseg_block\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mp\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;32mfor\u001b[0m \u001b[0mseg_block\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mp\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mzip\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mseg_blocks\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m[\u001b[0m\u001b[0mp5\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mp4\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mp3\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mp2\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 116\u001b[1;33m \u001b[0mx\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mmerge\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mfeature_pyramid\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 117\u001b[0m \u001b[0mx\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdropout\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mx\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 118\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n", 482 | "\u001b[1;32mD:\\Users\\PC\\Anaconda3\\envs\\pytorch2\\lib\\site-packages\\torch\\nn\\modules\\module.py\u001b[0m in \u001b[0;36m_call_impl\u001b[1;34m(self, *input, **kwargs)\u001b[0m\n\u001b[0;32m 891\u001b[0m \u001b[0m_global_forward_hooks\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mvalues\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 892\u001b[0m self._forward_hooks.values()):\n\u001b[1;32m--> 893\u001b[1;33m \u001b[0mhook_result\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mhook\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0minput\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mresult\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 894\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mhook_result\u001b[0m \u001b[1;32mis\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 895\u001b[0m \u001b[0mresult\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mhook_result\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 483 | "\u001b[1;32mD:\\Users\\PC\\Anaconda3\\envs\\pytorch2\\lib\\site-packages\\torchsummary\\torchsummary.py\u001b[0m in \u001b[0;36mhook\u001b[1;34m(module, input, output)\u001b[0m\n\u001b[0;32m 21\u001b[0m \u001b[0msummary\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mm_key\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;34m\"input_shape\"\u001b[0m\u001b[1;33m]\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mlist\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0minput\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msize\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 22\u001b[0m \u001b[1;32melif\u001b[0m \u001b[0misinstance\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0minput\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mlist\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 23\u001b[1;33m \u001b[0msummary\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mm_key\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;34m\"input_shape\"\u001b[0m\u001b[1;33m]\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mlist\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mnumpy\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0marray\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0minput\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msize\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 24\u001b[0m \u001b[1;31m#修改end here\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 25\u001b[0m \u001b[1;31m#summary[m_key][\"input_shape\"] = list(input[0].size())\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 484 | "\u001b[1;31mTypeError\u001b[0m: 'int' object is not callable" 485 | ] 486 | } 487 | ], 488 | "source": [ 489 | "summary(fpn,(3,320, 320))" 490 | ] 491 | }, 492 | { 493 | "cell_type": "code", 494 | "execution_count": 15, 495 | "metadata": {}, 496 | "outputs": [ 497 | { 498 | "name": "stdout", 499 | "output_type": "stream", 500 | "text": [ 501 | "FPN(\n", 502 | " (encoder): SENetEncoder(\n", 503 | " (layer0): Sequential(\n", 504 | " (conv1): Conv2d(3, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)\n", 505 | " (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 506 | " (relu1): ReLU(inplace=True)\n", 507 | " (pool): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=True)\n", 508 | " )\n", 509 | " (layer1): Sequential(\n", 510 | " (0): SEResNeXtBottleneck(\n", 511 | " (conv1): Conv2d(64, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", 512 | " (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 513 | " (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=32, bias=False)\n", 514 | " (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 515 | " (conv3): Conv2d(128, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", 516 | " (bn3): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 517 | " (relu): ReLU(inplace=True)\n", 518 | " (se_module): SEModule(\n", 519 | " (avg_pool): AdaptiveAvgPool2d(output_size=1)\n", 520 | " (fc1): Conv2d(256, 16, kernel_size=(1, 1), stride=(1, 1))\n", 521 | " (relu): ReLU(inplace=True)\n", 522 | " (fc2): Conv2d(16, 256, kernel_size=(1, 1), stride=(1, 1))\n", 523 | " (sigmoid): Sigmoid()\n", 524 | " )\n", 525 | " (downsample): Sequential(\n", 526 | " (0): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", 527 | " (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 528 | " )\n", 529 | " )\n", 530 | " (1): SEResNeXtBottleneck(\n", 531 | " (conv1): Conv2d(256, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", 532 | " (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 533 | " (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=32, bias=False)\n", 534 | " (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 535 | " (conv3): Conv2d(128, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", 536 | " (bn3): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 537 | " (relu): ReLU(inplace=True)\n", 538 | " (se_module): SEModule(\n", 539 | " (avg_pool): AdaptiveAvgPool2d(output_size=1)\n", 540 | " (fc1): Conv2d(256, 16, kernel_size=(1, 1), stride=(1, 1))\n", 541 | " (relu): ReLU(inplace=True)\n", 542 | " (fc2): Conv2d(16, 256, kernel_size=(1, 1), stride=(1, 1))\n", 543 | " (sigmoid): Sigmoid()\n", 544 | " )\n", 545 | " )\n", 546 | " (2): SEResNeXtBottleneck(\n", 547 | " (conv1): Conv2d(256, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", 548 | " (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 549 | " (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=32, bias=False)\n", 550 | " (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 551 | " (conv3): Conv2d(128, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", 552 | " (bn3): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 553 | " (relu): ReLU(inplace=True)\n", 554 | " (se_module): SEModule(\n", 555 | " (avg_pool): AdaptiveAvgPool2d(output_size=1)\n", 556 | " (fc1): Conv2d(256, 16, kernel_size=(1, 1), stride=(1, 1))\n", 557 | " (relu): ReLU(inplace=True)\n", 558 | " (fc2): Conv2d(16, 256, kernel_size=(1, 1), stride=(1, 1))\n", 559 | " (sigmoid): Sigmoid()\n", 560 | " )\n", 561 | " )\n", 562 | " )\n", 563 | " (layer2): Sequential(\n", 564 | " (0): SEResNeXtBottleneck(\n", 565 | " (conv1): Conv2d(256, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", 566 | " (bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 567 | " (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), groups=32, bias=False)\n", 568 | " (bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 569 | " (conv3): Conv2d(256, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", 570 | " (bn3): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 571 | " (relu): ReLU(inplace=True)\n", 572 | " (se_module): SEModule(\n", 573 | " (avg_pool): AdaptiveAvgPool2d(output_size=1)\n", 574 | " (fc1): Conv2d(512, 32, kernel_size=(1, 1), stride=(1, 1))\n", 575 | " (relu): ReLU(inplace=True)\n", 576 | " (fc2): Conv2d(32, 512, kernel_size=(1, 1), stride=(1, 1))\n", 577 | " (sigmoid): Sigmoid()\n", 578 | " )\n", 579 | " (downsample): Sequential(\n", 580 | " (0): Conv2d(256, 512, kernel_size=(1, 1), stride=(2, 2), bias=False)\n", 581 | " (1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 582 | " )\n", 583 | " )\n", 584 | " (1): SEResNeXtBottleneck(\n", 585 | " (conv1): Conv2d(512, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", 586 | " (bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 587 | " (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=32, bias=False)\n", 588 | " (bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 589 | " (conv3): Conv2d(256, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", 590 | " (bn3): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 591 | " (relu): ReLU(inplace=True)\n", 592 | " (se_module): SEModule(\n", 593 | " (avg_pool): AdaptiveAvgPool2d(output_size=1)\n", 594 | " (fc1): Conv2d(512, 32, kernel_size=(1, 1), stride=(1, 1))\n", 595 | " (relu): ReLU(inplace=True)\n", 596 | " (fc2): Conv2d(32, 512, kernel_size=(1, 1), stride=(1, 1))\n", 597 | " (sigmoid): Sigmoid()\n", 598 | " )\n", 599 | " )\n", 600 | " (2): SEResNeXtBottleneck(\n", 601 | " (conv1): Conv2d(512, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", 602 | " (bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 603 | " (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=32, bias=False)\n", 604 | " (bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 605 | " (conv3): Conv2d(256, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", 606 | " (bn3): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 607 | " (relu): ReLU(inplace=True)\n", 608 | " (se_module): SEModule(\n", 609 | " (avg_pool): AdaptiveAvgPool2d(output_size=1)\n", 610 | " (fc1): Conv2d(512, 32, kernel_size=(1, 1), stride=(1, 1))\n", 611 | " (relu): ReLU(inplace=True)\n", 612 | " (fc2): Conv2d(32, 512, kernel_size=(1, 1), stride=(1, 1))\n", 613 | " (sigmoid): Sigmoid()\n", 614 | " )\n", 615 | " )\n", 616 | " (3): SEResNeXtBottleneck(\n", 617 | " (conv1): Conv2d(512, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", 618 | " (bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 619 | " (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=32, bias=False)\n", 620 | " (bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 621 | " (conv3): Conv2d(256, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", 622 | " (bn3): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 623 | " (relu): ReLU(inplace=True)\n", 624 | " (se_module): SEModule(\n", 625 | " (avg_pool): AdaptiveAvgPool2d(output_size=1)\n", 626 | " (fc1): Conv2d(512, 32, kernel_size=(1, 1), stride=(1, 1))\n", 627 | " (relu): ReLU(inplace=True)\n", 628 | " (fc2): Conv2d(32, 512, kernel_size=(1, 1), stride=(1, 1))\n", 629 | " (sigmoid): Sigmoid()\n", 630 | " )\n", 631 | " )\n", 632 | " )\n", 633 | " (layer3): Sequential(\n", 634 | " (0): SEResNeXtBottleneck(\n", 635 | " (conv1): Conv2d(512, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", 636 | " (bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 637 | " (conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), groups=32, bias=False)\n", 638 | " (bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 639 | " (conv3): Conv2d(512, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", 640 | " (bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 641 | " (relu): ReLU(inplace=True)\n", 642 | " (se_module): SEModule(\n", 643 | " (avg_pool): AdaptiveAvgPool2d(output_size=1)\n", 644 | " (fc1): Conv2d(1024, 64, kernel_size=(1, 1), stride=(1, 1))\n", 645 | " (relu): ReLU(inplace=True)\n", 646 | " (fc2): Conv2d(64, 1024, kernel_size=(1, 1), stride=(1, 1))\n", 647 | " (sigmoid): Sigmoid()\n", 648 | " )\n", 649 | " (downsample): Sequential(\n", 650 | " (0): Conv2d(512, 1024, kernel_size=(1, 1), stride=(2, 2), bias=False)\n", 651 | " (1): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 652 | " )\n", 653 | " )\n", 654 | " (1): SEResNeXtBottleneck(\n", 655 | " (conv1): Conv2d(1024, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", 656 | " (bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 657 | " (conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=32, bias=False)\n", 658 | " (bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 659 | " (conv3): Conv2d(512, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", 660 | " (bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 661 | " (relu): ReLU(inplace=True)\n", 662 | " (se_module): SEModule(\n", 663 | " (avg_pool): AdaptiveAvgPool2d(output_size=1)\n", 664 | " (fc1): Conv2d(1024, 64, kernel_size=(1, 1), stride=(1, 1))\n", 665 | " (relu): ReLU(inplace=True)\n", 666 | " (fc2): Conv2d(64, 1024, kernel_size=(1, 1), stride=(1, 1))\n", 667 | " (sigmoid): Sigmoid()\n", 668 | " )\n", 669 | " )\n", 670 | " (2): SEResNeXtBottleneck(\n", 671 | " (conv1): Conv2d(1024, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", 672 | " (bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 673 | " (conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=32, bias=False)\n", 674 | " (bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 675 | " (conv3): Conv2d(512, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", 676 | " (bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 677 | " (relu): ReLU(inplace=True)\n", 678 | " (se_module): SEModule(\n", 679 | " (avg_pool): AdaptiveAvgPool2d(output_size=1)\n", 680 | " (fc1): Conv2d(1024, 64, kernel_size=(1, 1), stride=(1, 1))\n", 681 | " (relu): ReLU(inplace=True)\n", 682 | " (fc2): Conv2d(64, 1024, kernel_size=(1, 1), stride=(1, 1))\n", 683 | " (sigmoid): Sigmoid()\n", 684 | " )\n", 685 | " )\n", 686 | " (3): SEResNeXtBottleneck(\n", 687 | " (conv1): Conv2d(1024, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", 688 | " (bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 689 | " (conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=32, bias=False)\n", 690 | " (bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 691 | " (conv3): Conv2d(512, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", 692 | " (bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 693 | " (relu): ReLU(inplace=True)\n", 694 | " (se_module): SEModule(\n", 695 | " (avg_pool): AdaptiveAvgPool2d(output_size=1)\n", 696 | " (fc1): Conv2d(1024, 64, kernel_size=(1, 1), stride=(1, 1))\n", 697 | " (relu): ReLU(inplace=True)\n", 698 | " (fc2): Conv2d(64, 1024, kernel_size=(1, 1), stride=(1, 1))\n", 699 | " (sigmoid): Sigmoid()\n", 700 | " )\n", 701 | " )\n", 702 | " (4): SEResNeXtBottleneck(\n", 703 | " (conv1): Conv2d(1024, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", 704 | " (bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 705 | " (conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=32, bias=False)\n", 706 | " (bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 707 | " (conv3): Conv2d(512, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", 708 | " (bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 709 | " (relu): ReLU(inplace=True)\n", 710 | " (se_module): SEModule(\n", 711 | " (avg_pool): AdaptiveAvgPool2d(output_size=1)\n", 712 | " (fc1): Conv2d(1024, 64, kernel_size=(1, 1), stride=(1, 1))\n", 713 | " (relu): ReLU(inplace=True)\n", 714 | " (fc2): Conv2d(64, 1024, kernel_size=(1, 1), stride=(1, 1))\n", 715 | " (sigmoid): Sigmoid()\n", 716 | " )\n", 717 | " )\n", 718 | " (5): SEResNeXtBottleneck(\n", 719 | " (conv1): Conv2d(1024, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", 720 | " (bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 721 | " (conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=32, bias=False)\n", 722 | " (bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 723 | " (conv3): Conv2d(512, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", 724 | " (bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 725 | " (relu): ReLU(inplace=True)\n", 726 | " (se_module): SEModule(\n", 727 | " (avg_pool): AdaptiveAvgPool2d(output_size=1)\n", 728 | " (fc1): Conv2d(1024, 64, kernel_size=(1, 1), stride=(1, 1))\n", 729 | " (relu): ReLU(inplace=True)\n", 730 | " (fc2): Conv2d(64, 1024, kernel_size=(1, 1), stride=(1, 1))\n", 731 | " (sigmoid): Sigmoid()\n", 732 | " )\n", 733 | " )\n", 734 | " )\n", 735 | " (layer4): Sequential(\n", 736 | " (0): SEResNeXtBottleneck(\n", 737 | " (conv1): Conv2d(1024, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", 738 | " (bn1): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 739 | " (conv2): Conv2d(1024, 1024, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), groups=32, bias=False)\n", 740 | " (bn2): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 741 | " (conv3): Conv2d(1024, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", 742 | " (bn3): BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 743 | " (relu): ReLU(inplace=True)\n", 744 | " (se_module): SEModule(\n", 745 | " (avg_pool): AdaptiveAvgPool2d(output_size=1)\n", 746 | " (fc1): Conv2d(2048, 128, kernel_size=(1, 1), stride=(1, 1))\n", 747 | " (relu): ReLU(inplace=True)\n", 748 | " (fc2): Conv2d(128, 2048, kernel_size=(1, 1), stride=(1, 1))\n", 749 | " (sigmoid): Sigmoid()\n", 750 | " )\n", 751 | " (downsample): Sequential(\n", 752 | " (0): Conv2d(1024, 2048, kernel_size=(1, 1), stride=(2, 2), bias=False)\n", 753 | " (1): BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 754 | " )\n", 755 | " )\n", 756 | " (1): SEResNeXtBottleneck(\n", 757 | " (conv1): Conv2d(2048, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", 758 | " (bn1): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 759 | " (conv2): Conv2d(1024, 1024, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=32, bias=False)\n", 760 | " (bn2): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 761 | " (conv3): Conv2d(1024, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", 762 | " (bn3): BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 763 | " (relu): ReLU(inplace=True)\n", 764 | " (se_module): SEModule(\n", 765 | " (avg_pool): AdaptiveAvgPool2d(output_size=1)\n", 766 | " (fc1): Conv2d(2048, 128, kernel_size=(1, 1), stride=(1, 1))\n", 767 | " (relu): ReLU(inplace=True)\n", 768 | " (fc2): Conv2d(128, 2048, kernel_size=(1, 1), stride=(1, 1))\n", 769 | " (sigmoid): Sigmoid()\n", 770 | " )\n", 771 | " )\n", 772 | " (2): SEResNeXtBottleneck(\n", 773 | " (conv1): Conv2d(2048, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", 774 | " (bn1): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 775 | " (conv2): Conv2d(1024, 1024, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=32, bias=False)\n", 776 | " (bn2): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 777 | " (conv3): Conv2d(1024, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", 778 | " (bn3): BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", 779 | " (relu): ReLU(inplace=True)\n", 780 | " (se_module): SEModule(\n", 781 | " (avg_pool): AdaptiveAvgPool2d(output_size=1)\n", 782 | " (fc1): Conv2d(2048, 128, kernel_size=(1, 1), stride=(1, 1))\n", 783 | " (relu): ReLU(inplace=True)\n", 784 | " (fc2): Conv2d(128, 2048, kernel_size=(1, 1), stride=(1, 1))\n", 785 | " (sigmoid): Sigmoid()\n", 786 | " )\n", 787 | " )\n", 788 | " )\n", 789 | " )\n", 790 | " (decoder): FPNDecoder(\n", 791 | " (p5): Conv2d(2048, 256, kernel_size=(1, 1), stride=(1, 1))\n", 792 | " (p4): FPNBlock(\n", 793 | " (skip_conv): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1))\n", 794 | " )\n", 795 | " (p3): FPNBlock(\n", 796 | " (skip_conv): Conv2d(512, 256, kernel_size=(1, 1), stride=(1, 1))\n", 797 | " )\n", 798 | " (p2): FPNBlock(\n", 799 | " (skip_conv): Conv2d(256, 256, kernel_size=(1, 1), stride=(1, 1))\n", 800 | " )\n", 801 | " (seg_blocks): ModuleList(\n", 802 | " (0): SegmentationBlock(\n", 803 | " (block): Sequential(\n", 804 | " (0): Conv3x3GNReLU(\n", 805 | " (block): Sequential(\n", 806 | " (0): Conv2d(256, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n", 807 | " (1): GroupNorm(32, 128, eps=1e-05, affine=True)\n", 808 | " (2): ReLU(inplace=True)\n", 809 | " )\n", 810 | " )\n", 811 | " (1): Conv3x3GNReLU(\n", 812 | " (block): Sequential(\n", 813 | " (0): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n", 814 | " (1): GroupNorm(32, 128, eps=1e-05, affine=True)\n", 815 | " (2): ReLU(inplace=True)\n", 816 | " )\n", 817 | " )\n", 818 | " (2): Conv3x3GNReLU(\n", 819 | " (block): Sequential(\n", 820 | " (0): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n", 821 | " (1): GroupNorm(32, 128, eps=1e-05, affine=True)\n", 822 | " (2): ReLU(inplace=True)\n", 823 | " )\n", 824 | " )\n", 825 | " )\n", 826 | " )\n", 827 | " (1): SegmentationBlock(\n", 828 | " (block): Sequential(\n", 829 | " (0): Conv3x3GNReLU(\n", 830 | " (block): Sequential(\n", 831 | " (0): Conv2d(256, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n", 832 | " (1): GroupNorm(32, 128, eps=1e-05, affine=True)\n", 833 | " (2): ReLU(inplace=True)\n", 834 | " )\n", 835 | " )\n", 836 | " (1): Conv3x3GNReLU(\n", 837 | " (block): Sequential(\n", 838 | " (0): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n", 839 | " (1): GroupNorm(32, 128, eps=1e-05, affine=True)\n", 840 | " (2): ReLU(inplace=True)\n", 841 | " )\n", 842 | " )\n", 843 | " )\n", 844 | " )\n", 845 | " (2): SegmentationBlock(\n", 846 | " (block): Sequential(\n", 847 | " (0): Conv3x3GNReLU(\n", 848 | " (block): Sequential(\n", 849 | " (0): Conv2d(256, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n", 850 | " (1): GroupNorm(32, 128, eps=1e-05, affine=True)\n", 851 | " (2): ReLU(inplace=True)\n", 852 | " )\n", 853 | " )\n", 854 | " )\n", 855 | " )\n", 856 | " (3): SegmentationBlock(\n", 857 | " (block): Sequential(\n", 858 | " (0): Conv3x3GNReLU(\n", 859 | " (block): Sequential(\n", 860 | " (0): Conv2d(256, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n", 861 | " (1): GroupNorm(32, 128, eps=1e-05, affine=True)\n", 862 | " (2): ReLU(inplace=True)\n", 863 | " )\n", 864 | " )\n", 865 | " )\n", 866 | " )\n", 867 | " )\n", 868 | " (merge): MergeBlock()\n", 869 | " (dropout): Dropout2d(p=0.2, inplace=True)\n", 870 | " )\n", 871 | " (segmentation_head): SegmentationHead(\n", 872 | " (0): Conv2d(128, 1, kernel_size=(1, 1), stride=(1, 1))\n", 873 | " (1): UpsamplingBilinear2d(scale_factor=4.0, mode=bilinear)\n", 874 | " (2): Activation(\n", 875 | " (activation): Sigmoid()\n", 876 | " )\n", 877 | " )\n", 878 | ")\n" 879 | ] 880 | } 881 | ], 882 | "source": [] 883 | } 884 | ], 885 | "metadata": { 886 | "kernelspec": { 887 | "display_name": "Python [conda env:pytorch2]", 888 | "language": "python", 889 | "name": "conda-env-pytorch2-py" 890 | }, 891 | "language_info": { 892 | "codemirror_mode": { 893 | "name": "ipython", 894 | "version": 3 895 | }, 896 | "file_extension": ".py", 897 | "mimetype": "text/x-python", 898 | "name": "python", 899 | "nbconvert_exporter": "python", 900 | "pygments_lexer": "ipython3", 901 | "version": "3.6.2" 902 | } 903 | }, 904 | "nbformat": 4, 905 | "nbformat_minor": 4 906 | } 907 | --------------------------------------------------------------------------------