├── 2019-tip-deepcrack.pdf ├── README.md ├── codes ├── checkpoints │ └── 111 ├── config.py ├── data │ ├── 111 │ ├── augmentation.py │ ├── dataset.py │ ├── train_example.txt │ └── val_example.txt ├── model │ ├── 111 │ └── deepcrack.py ├── test.py ├── tools │ ├── 111 │ ├── checkpointer.py │ ├── paths.py │ └── visdom.py ├── train.py └── trainer.py └── figures ├── 1000.png ├── 1014.png ├── 1022.png ├── 1042.png ├── 1045.png ├── 1065.png ├── 1095.png ├── 1096.png ├── 6192.jpg ├── 6207.jpg ├── 6264.jpg ├── 6328.jpg ├── 6750.jpg ├── DSCN6428.JPG ├── deepcrack-compare1.png ├── deepcrack-compare2.png ├── deepcrack-compare3.png ├── fig ├── intro.png └── network.png /2019-tip-deepcrack.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qinnzou/DeepCrack/f3988031dd2adc3d19b32d1c48a2bf90d12871ac/2019-tip-deepcrack.pdf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DeepCrack: Learning Hierarchical Convolutional Features for Crack Detection 2 | 3 | We provide the codes, the datasets, and the pretrained model. 4 | 5 | Zou Q, Zhang Z, Li Q, Qi X, Wang Q and Wang S, DeepCrack: Learning Hierarchical Convolutional Features for Crack Detection, IEEE Transactions on Image Processing, vol. 28, no. 3, pp. 1498-1512, 2019. [ [PDF] ](http://mvr.whu.edu.cn/pubs/2019-tip-deepcrack.pdf) 6 | 7 | - Abstract: Cracks are typical line structures that are of interest in many computer-vision applications. In practice, many cracks, e.g., pavement cracks, show poor continuity and low contrast, which bring great challenges to image-based crack detection by using low-level features. In this paper, we propose DeepCrack-an end-to-end trainable deep convolutional neural network for automatic crack detection by learning high-level features for crack representation. In this method, multi-scale deep convolutional features learned at hierarchical convolutional stages are fused together to capture the line structures. More detailed representations are made in larger scale feature maps and more holistic representations are made in smaller scale feature maps. We build DeepCrack net on the encoder-decoder architecture of SegNet and pairwisely fuse the convolutional features generated in the encoder network and in the decoder network at the same scale. We train DeepCrack net on one crack dataset and evaluate it on three others. The experimental results demonstrate that DeepCrack achieves F -measure over 0.87 on the three challenging datasets in average and outperforms the current state-of-the-art methods. 8 | 9 | # Network Architecture 10 | ![image](https://github.com/qinnzou/DeepCrack/blob/master/figures/network.png) 11 | # Some Results 12 | ![image](https://github.com/qinnzou/DeepCrack/blob/master/figures/intro.png) 13 | 14 | # DeepCrack Datasets 15 | Four datasets are used by DeepCrack. CrackTree260 is used for training, and the other three are used for test. 16 | 17 | ## CrackTree260 dataset 18 | 19 |
20 | 21 | 22 | 23 |
24 | 25 |
26 | 27 | 28 | 29 |
30 | 31 | + It contains 260 road pavement images - an expansion of the dataset used in [CrackTree, PRL, 2012]. These pavement images are captured by an area-array camera under visible-light illumination. We use all 260 images for training. Data augmentation has been performed to enlarge the size of the training set. We rotate the images with 9 different angles (from 0-90 degrees at an interval of 10), flip the image in the vertical and horizontal direction at each angle, and crop 5 subimages (with 4 at the corners and 1 in the center) on each flipped image with a size of 512×512. After augmentation, we get a training set of 35,100 images in total. 32 | ## CRKWH100 dataset 33 | 34 |
35 | 36 | 37 | 38 | 39 |
40 | 41 |
42 | 43 | 44 | 45 | 46 |
47 | 48 | + It contains 100 road pavement images captured by a line-array camera under visible-light illumination. The line-array camera captures the pavement at a ground sampling distance of 1 millimeter. 49 | ## CrackLS315 dataset 50 | - It contains 315 road pavement images captured under laser illumination. These images are also captured by a line-array camera, at the same ground sampling distance. 51 | ## Stone331 dataset 52 | - It contains 331 images of stone surface. When cutting the stone, cracks may occur on the cutting surface. These images are captured by an area-array camera under visible-light illumination. We produce a mask for the area of each stone surface in the image. Then the performance evaluation can be constrained in the stone surface. 53 | 54 | 55 | ## Download: 56 | You can download the four datasets from the following link, 57 | ``` 58 | CrackTree260 & GT dataset: https://1drv.ms/f/s!AittnGm6vRKLyiQUk3ViLu8L9Wzb 59 | 60 | CRKWH100 dataset: https://1drv.ms/f/s!AittnGm6vRKLtylBkxVXw5arGn6R 61 | CRKWH100 GT: https://1drv.ms/f/s!AittnGm6vRKLglyfiCw_C6BDeFsP 62 | 63 | CrackLS315 dataset: https://1drv.ms/f/s!AittnGm6vRKLtylBkxVXw5arGn6R 64 | CrackLS315 GT: https://1drv.ms/u/s!AittnGm6vRKLg0HrFfJNhP2Ne1L5?e=WYbPvF 65 | 66 | Stone331 dataset: https://1drv.ms/f/s!AittnGm6vRKLtylBkxVXw5arGn6R 67 | Stone331 GT: https://1drv.ms/f/s!AittnGm6vRKLwiL55f7f0xdpuD9_ 68 | Stone331 Mask: https://1drv.ms/u/s!AittnGm6vRKLxmFB78iKSxTzNLRV?e=9Ph5aP 69 | ``` 70 | 71 | You can also download the datasets from 72 | link:https://pan.baidu.com/s/1PWiBzoJlc8qC8ffZu2Vb8w 73 | passcodes:zfoo 74 | 75 | ## Results: 76 | Some results on our datasets: 77 | ![image](https://github.com/qinnzou/deepcrack/blob/master/figures/deepcrack-compare1.png) 78 | ![image](https://github.com/qinnzou/deepcrack/blob/master/figures/deepcrack-compare2.png) 79 | ![image](https://github.com/qinnzou/deepcrack/blob/master/figures/deepcrack-compare3.png) 80 | 81 | # Set up 82 | ## Requirements 83 | PyTorch 1.0.2 or above 84 | Python 3.6 85 | CUDA 10.0 86 | We run on the Intel Core Xeon E5-2630@2.3GHz, 64GB RAM and two GeForce GTX TITAN-X GPUs. 87 | 88 | ## Pretrained Models 89 | Pretrained models on PyTorch are available at, 90 | https://drive.google.com/file/d/1OO3OAzR4yxYh_UBR9Nu7hV3XayfKVyO-/view?usp=sharing 91 | or at link:https://pan.baidu.com/s/1WsIwVnDgtRBpJF8ktlN84A 92 | passcode:27py 93 | You can download them and put them into "./codes/checkpoints/". 94 | 95 | 96 | ``` 97 | Please notice that, as this model was trained with Pytorch, its performance is slightly different with that of the original version built on Caffe. 98 | ``` 99 | 100 | ## Training 101 | Before training, change the paths including "train_path"(for train_index.txt), "pretrained_path" in config.py to adapt to your environment. 102 | Choose the models and adjust the arguments such as class weights, batch size, learning rate in config.py. 103 | Then simply run: 104 | ``` 105 | python train.py 106 | ``` 107 | 108 | ## Test 109 | To evlauate the performance of a pre-trained model, please put the pretrained model listed above or your own models into "./codes/checkpoints/" and change "pretrained_path" in config.py at first, then change "test_path" for test_index.txt, and "save_path" for the saved results. 110 | Choose the right model that would be evlauated, and then simply run: 111 | ``` 112 | python test.py 113 | ``` 114 | 115 | # Citation: 116 | If you use our codes or datasets in your own research, the citation can be placed as: 117 | ``` 118 | @article{zou2018deepcrack, 119 | title={Deepcrack: Learning Hierarchical Convolutional Features for Crack Detection}, 120 | author={Zou, Qin and Zhang, Zheng and Li, Qingquan and Qi, Xianbiao and Wang, Qian and Wang, Song}, 121 | journal={IEEE Transactions on Image Processing}, 122 | volume={28}, 123 | number={3}, 124 | pages={1498--1512}, 125 | year={2019}, 126 | } 127 | ``` 128 | The CrackTree260 dataset was constructed based on the CrackTree206 dataset. For details, you can refer to 129 | ``` 130 | @article{zou2012cracktree, 131 | title={CrackTree: Automatic crack detection from pavement images}, 132 | author={Zou, Qin and Cao, Yu and Li, Qingquan and Mao, Qingzhou and Wang, Song}, 133 | journal={Pattern Recognition Letters}, 134 | volume={33}, 135 | number={3}, 136 | pages={227--238}, 137 | year={2012}, 138 | publisher={Elsevier} 139 | } 140 | ``` 141 | # Copy Right: 142 | This dataset was collected for academic research. 143 | # Contact: 144 | For any problem about this dataset or codes, please contact Dr. Qin Zou (qzou@whu.edu.cn). 145 | -------------------------------------------------------------------------------- /codes/checkpoints/111: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /codes/config.py: -------------------------------------------------------------------------------- 1 | from pprint import pprint 2 | import os 3 | import setproctitle 4 | 5 | class Config: 6 | name = 'DeepCrack_CT260_FT1' 7 | 8 | gpu_id = '0,1,2,3' 9 | 10 | setproctitle.setproctitle("%s" % name) 11 | 12 | # path 13 | train_data_path = 'data/train_example.txt' 14 | val_data_path = 'data/test_example.txt' 15 | checkpoint_path = 'checkpoints' 16 | log_path = 'log' 17 | saver_path = os.path.join(checkpoint_path, name) 18 | max_save = 20 19 | 20 | # visdom 21 | vis_env = 'DeepCrack' 22 | port = 8097 23 | vis_train_loss_every = 40 24 | vis_train_acc_every = 40 25 | vis_train_img_every = 120 26 | val_every = 200 27 | 28 | # training 29 | epoch = 500 30 | pretrained_model = '' 31 | weight_decay = 0.0000 32 | lr_decay = 0.1 33 | lr = 1e-3 34 | momentum = 0.9 35 | use_adam = True # Use Adam optimizer 36 | train_batch_size = 8 37 | val_batch_size = 4 38 | test_batch_size = 4 39 | 40 | acc_sigmoid_th = 0.5 41 | pos_pixel_weight = 1 42 | 43 | # checkpointer 44 | save_format = '' 45 | save_acc = -1 46 | save_pos_acc = -1 47 | 48 | def _parse(self, kwargs): 49 | state_dict = self._state_dict() 50 | for k, v in kwargs.items(): 51 | if k not in state_dict: 52 | raise ValueError('UnKnown Option: "--%s"' % k) 53 | setattr(self, k, v) 54 | 55 | print('======user config========') 56 | pprint(self._state_dict()) 57 | print('==========end============') 58 | 59 | def _state_dict(self): 60 | return {k: getattr(self, k) for k, _ in Config.__dict__.items() \ 61 | if not k.startswith('_')} 62 | 63 | def show(self): 64 | print('======user config========') 65 | pprint(self._state_dict()) 66 | print('==========end============') 67 | -------------------------------------------------------------------------------- /codes/data/111: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /codes/data/augmentation.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import cv2 3 | 4 | def t_random(min=0, max=1): 5 | return min + (max - min) * np.random.rand() 6 | 7 | 8 | def t_randint(min, max): 9 | return np.random.randint(low=min, high=max) 10 | 11 | class augCompose(object): 12 | 13 | def __init__(self, transforms=None): 14 | self.transforms = transforms 15 | 16 | def __call__(self, img, mask): 17 | 18 | if self.transforms is not None: 19 | for op, prob in self.transforms: 20 | if t_random() <= prob: 21 | img, mask = op(img, mask) 22 | 23 | return img, mask 24 | 25 | def RandomFlip(img, mask, FLIP_LEFT_RIGHT=True, FLIP_TOP_BOTTOM=True): 26 | 27 | if FLIP_LEFT_RIGHT and t_random() < 0.5: 28 | img = cv2.flip(img, 1) 29 | mask = cv2.flip(mask, 1) 30 | 31 | if FLIP_TOP_BOTTOM and t_random() < 0.5: 32 | img = cv2.flip(img, 0) 33 | mask = cv2.flip(mask, 0) 34 | return img, mask 35 | 36 | 37 | def RandomBlur(img, mask): 38 | 39 | r = 5 40 | 41 | if t_random() < 0.2: 42 | return cv2.GaussianBlur(img,(r,r),0), mask 43 | 44 | if t_random() < 0.15: 45 | return cv2.blur(img,(r,r)), mask 46 | 47 | if t_random() < 0.1: 48 | return cv2.medianBlur(img,r), mask 49 | 50 | 51 | return img, mask 52 | 53 | def RandomColorJitter(img, mask, brightness=32, contrast=0.5, saturation=0.5, hue=0.1, 54 | prob=0.5): 55 | if brightness != 0 and t_random() > prob: 56 | img = _Brightness(img, delta=brightness) 57 | if contrast != 0 and t_random() > prob: 58 | img = _Contrast(img, var=contrast) 59 | if saturation != 0 and t_random() > prob: 60 | img = _Saturation(img, var=saturation) 61 | if hue != 0 and t_random() > prob: 62 | img = _Hue(img, var=hue) 63 | 64 | return img, mask 65 | 66 | 67 | def _Brightness(img, delta=32): 68 | img = img.astype(np.float32) + t_random(-delta, delta) 69 | img = np.clip(img, 0, 255) 70 | return img.astype(np.uint8) 71 | 72 | 73 | def _Contrast(img, var=0.3): 74 | gs = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY).mean() 75 | alpha = 1.0 + t_random(-var, var) 76 | img = alpha * img.astype(np.float32) + (1 - alpha) * gs 77 | img = np.clip(img, 0, 255) 78 | return img.astype(np.uint8) 79 | 80 | 81 | def _Hue(img, var=0.05): 82 | var = t_random(-var, var) 83 | to_HSV, from_HSV = [ 84 | (cv2.COLOR_RGB2HSV, cv2.COLOR_HSV2RGB), 85 | (cv2.COLOR_BGR2HSV, cv2.COLOR_HSV2BGR)][t_randint(0, 2)] 86 | hsv = cv2.cvtColor(img, to_HSV).astype(np.float32) 87 | 88 | hue = hsv[:, :, 0] / 179. + var 89 | hue = hue - np.floor(hue) 90 | hsv[:, :, 0] = hue * 179. 91 | 92 | img = cv2.cvtColor(hsv.astype('uint8'), from_HSV) 93 | return img 94 | 95 | 96 | def _Saturation(img, var=0.3): 97 | gs = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 98 | gs = np.expand_dims(gs, axis=2) 99 | alpha = 1.0 + t_random(-var, var) 100 | img = alpha * img.astype(np.float32) + (1 - alpha) * gs.astype(np.float32) 101 | img = np.clip(img, 0, 255) 102 | return img.astype(np.uint8) 103 | 104 | 105 | -------------------------------------------------------------------------------- /codes/data/dataset.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import numpy as np 3 | from torch.utils.data import Dataset 4 | import torch 5 | import random 6 | 7 | 8 | def readIndex(index_path, shuffle=False): 9 | img_list = [] 10 | with open(index_path, 'r') as file_to_read: 11 | while True: 12 | lines = file_to_read.readline() 13 | if not lines: 14 | break 15 | item = lines.strip().split() 16 | img_list.append(item) 17 | file_to_read.close() 18 | if shuffle is True: 19 | random.shuffle(img_list) 20 | return img_list 21 | 22 | class dataReadPip(object): 23 | 24 | def __init__(self, transforms=None): 25 | self.transforms = transforms 26 | 27 | def __call__(self, item): 28 | 29 | img = cv2.imread(item[0]) 30 | lab = cv2.imread(item[1]) 31 | 32 | 33 | if len(lab.shape) != 2: 34 | lab = cv2.cvtColor(lab, cv2.COLOR_BGR2GRAY) 35 | 36 | 37 | if self.transforms is not None: 38 | 39 | img, lab = self.transforms(img, lab) 40 | 41 | img = _preprocess_img(img) 42 | lab = _preprocess_lab(lab) 43 | return img, lab 44 | 45 | 46 | def _preprocess_img(cvImage): 47 | ''' 48 | :param cvImage: numpy HWC BGR 0~255 49 | :return: tensor img CHW BGR float32 cpu 0~1 50 | ''' 51 | 52 | cvImage = cvImage.transpose(2, 0, 1).astype(np.float32) / 255 53 | 54 | 55 | return torch.from_numpy(cvImage) 56 | 57 | def _preprocess_lab(cvImage): 58 | ''' 59 | :param cvImage: numpy 0(background) or 255(crack pixel) 60 | :return: tensor 0 or 1 float32 61 | ''' 62 | cvImage = cvImage.astype(np.float32) / 255 63 | 64 | return torch.from_numpy(cvImage) 65 | 66 | 67 | class loadedDataset(Dataset): 68 | """ 69 | Create a torch Dataset from data 70 | """ 71 | 72 | def __init__(self, dataset, preprocess=None): 73 | super(loadedDataset, self).__init__() 74 | self.dataset = dataset 75 | if preprocess is None: 76 | preprocess = lambda x: x 77 | self.preprocess = preprocess 78 | 79 | def __getitem__(self, index): 80 | return self.preprocess(self.dataset[index]) 81 | 82 | def __len__(self): 83 | return len(self.dataset) 84 | 85 | 86 | -------------------------------------------------------------------------------- /codes/data/train_example.txt: -------------------------------------------------------------------------------- 1 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot0_crop1_mirror0.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot0_crop1_mirror0.png 2 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot0_crop1_mirror1.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot0_crop1_mirror1.png 3 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot0_crop1_mirror2.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot0_crop1_mirror2.png 4 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot0_crop2_mirror0.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot0_crop2_mirror0.png 5 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot0_crop2_mirror1.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot0_crop2_mirror1.png 6 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot0_crop2_mirror2.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot0_crop2_mirror2.png 7 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot0_crop3_mirror0.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot0_crop3_mirror0.png 8 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot0_crop3_mirror1.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot0_crop3_mirror1.png 9 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot0_crop3_mirror2.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot0_crop3_mirror2.png 10 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot0_crop4_mirror0.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot0_crop4_mirror0.png 11 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot0_crop4_mirror1.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot0_crop4_mirror1.png 12 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot0_crop4_mirror2.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot0_crop4_mirror2.png 13 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot0_crop5_mirror0.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot0_crop5_mirror0.png 14 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot0_crop5_mirror1.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot0_crop5_mirror1.png 15 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot0_crop5_mirror2.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot0_crop5_mirror2.png 16 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot1_crop1_mirror0.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot1_crop1_mirror0.png 17 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot1_crop1_mirror1.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot1_crop1_mirror1.png 18 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot1_crop1_mirror2.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot1_crop1_mirror2.png 19 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot1_crop2_mirror0.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot1_crop2_mirror0.png 20 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot1_crop2_mirror1.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot1_crop2_mirror1.png 21 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot1_crop2_mirror2.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot1_crop2_mirror2.png 22 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot1_crop3_mirror0.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot1_crop3_mirror0.png 23 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot1_crop3_mirror1.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot1_crop3_mirror1.png 24 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot1_crop3_mirror2.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot1_crop3_mirror2.png 25 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot1_crop4_mirror0.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot1_crop4_mirror0.png 26 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot1_crop4_mirror1.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot1_crop4_mirror1.png 27 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot1_crop4_mirror2.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot1_crop4_mirror2.png 28 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot1_crop5_mirror0.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot1_crop5_mirror0.png 29 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot1_crop5_mirror1.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot1_crop5_mirror1.png 30 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot1_crop5_mirror2.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot1_crop5_mirror2.png 31 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot2_crop1_mirror0.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot2_crop1_mirror0.png 32 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot2_crop1_mirror1.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot2_crop1_mirror1.png 33 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot2_crop1_mirror2.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot2_crop1_mirror2.png 34 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot2_crop2_mirror0.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot2_crop2_mirror0.png 35 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot2_crop2_mirror1.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot2_crop2_mirror1.png 36 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot2_crop2_mirror2.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot2_crop2_mirror2.png 37 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot2_crop3_mirror0.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot2_crop3_mirror0.png 38 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot2_crop3_mirror1.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot2_crop3_mirror1.png 39 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot2_crop3_mirror2.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot2_crop3_mirror2.png 40 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot2_crop4_mirror0.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot2_crop4_mirror0.png 41 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot2_crop4_mirror1.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot2_crop4_mirror1.png 42 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot2_crop4_mirror2.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot2_crop4_mirror2.png 43 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot2_crop5_mirror0.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot2_crop5_mirror0.png 44 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot2_crop5_mirror1.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot2_crop5_mirror1.png 45 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot2_crop5_mirror2.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot2_crop5_mirror2.png 46 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot3_crop1_mirror0.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot3_crop1_mirror0.png 47 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot3_crop1_mirror1.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot3_crop1_mirror1.png 48 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot3_crop1_mirror2.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot3_crop1_mirror2.png 49 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot3_crop2_mirror0.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot3_crop2_mirror0.png 50 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot3_crop2_mirror1.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot3_crop2_mirror1.png 51 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot3_crop2_mirror2.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot3_crop2_mirror2.png 52 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot3_crop3_mirror0.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot3_crop3_mirror0.png 53 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot3_crop3_mirror1.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot3_crop3_mirror1.png 54 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot3_crop3_mirror2.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot3_crop3_mirror2.png 55 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_image/6192_rot3_crop4_mirror0.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_train_mask/6192_rot3_crop4_mirror0.png -------------------------------------------------------------------------------- /codes/data/val_example.txt: -------------------------------------------------------------------------------- 1 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6428_rot2_crop3.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6428_rot2_crop3.png 2 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6429_rot5_crop2.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6429_rot5_crop2.png 3 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6431_rot0_crop3.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6431_rot0_crop3.png 4 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6431_rot2_crop2.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6431_rot2_crop2.png 5 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6431_rot5_crop2.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6431_rot5_crop2.png 6 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6431_rot7_crop5.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6431_rot7_crop5.png 7 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6431_rot8_crop1.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6431_rot8_crop1.png 8 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6432_rot1_crop1.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6432_rot1_crop1.png 9 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6432_rot2_crop1.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6432_rot2_crop1.png 10 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6432_rot3_crop3.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6432_rot3_crop3.png 11 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6432_rot4_crop2.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6432_rot4_crop2.png 12 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6432_rot7_crop1.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6432_rot7_crop1.png 13 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6434_rot2_crop2.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6434_rot2_crop2.png 14 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6434_rot3_crop4.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6434_rot3_crop4.png 15 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6436_rot5_crop5.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6436_rot5_crop5.png 16 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6436_rot8_crop1.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6436_rot8_crop1.png 17 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6437_rot2_crop2.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6437_rot2_crop2.png 18 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6437_rot8_crop4.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6437_rot8_crop4.png 19 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6439_rot3_crop1.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6439_rot3_crop1.png 20 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6439_rot3_crop4.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6439_rot3_crop4.png 21 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6439_rot6_crop3.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6439_rot6_crop3.png 22 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6440_rot1_crop1.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6440_rot1_crop1.png 23 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6440_rot1_crop5.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6440_rot1_crop5.png 24 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6440_rot2_crop5.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6440_rot2_crop5.png 25 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6440_rot5_crop2.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6440_rot5_crop2.png 26 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6441_rot6_crop2.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6441_rot6_crop2.png 27 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6441_rot7_crop2.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6441_rot7_crop2.png 28 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6441_rot7_crop4.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6441_rot7_crop4.png 29 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6441_rot8_crop2.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6441_rot8_crop2.png 30 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6442_rot0_crop4.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6442_rot0_crop4.png 31 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6443_rot0_crop3.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6443_rot0_crop3.png 32 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6443_rot3_crop3.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6443_rot3_crop3.png 33 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6443_rot8_crop3.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6443_rot8_crop3.png 34 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6444_rot4_crop1.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6444_rot4_crop1.png 35 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6445_rot0_crop5.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6445_rot0_crop5.png 36 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6445_rot1_crop3.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6445_rot1_crop3.png 37 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6445_rot4_crop2.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6445_rot4_crop2.png 38 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6445_rot7_crop4.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6445_rot7_crop4.png 39 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6446_rot0_crop4.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6446_rot0_crop4.png 40 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6446_rot5_crop4.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6446_rot5_crop4.png 41 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6446_rot6_crop4.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6446_rot6_crop4.png 42 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6446_rot8_crop3.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6446_rot8_crop3.png 43 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6447_rot7_crop1.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6447_rot7_crop1.png 44 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6450_rot3_crop3.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6450_rot3_crop3.png 45 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6450_rot6_crop5.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6450_rot6_crop5.png 46 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6450_rot7_crop2.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6450_rot7_crop2.png 47 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6450_rot7_crop5.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6450_rot7_crop5.png 48 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6450_rot8_crop2.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6450_rot8_crop2.png 49 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6450_rot8_crop4.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6450_rot8_crop4.png 50 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6450_rot8_crop5.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6450_rot8_crop5.png 51 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6452_rot3_crop5.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6452_rot3_crop5.png 52 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6452_rot4_crop4.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6452_rot4_crop4.png 53 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6453_rot1_crop1.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6453_rot1_crop1.png 54 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6453_rot2_crop2.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6453_rot2_crop2.png 55 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6453_rot5_crop2.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6453_rot5_crop2.png 56 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6455_rot6_crop1.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6455_rot6_crop1.png 57 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6455_rot8_crop3.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6455_rot8_crop3.png 58 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6469_rot4_crop2.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6469_rot4_crop2.png 59 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6469_rot7_crop5.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6469_rot7_crop5.png 60 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6469_rot8_crop3.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6469_rot8_crop3.png 61 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6470_rot2_crop1.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6470_rot2_crop1.png 62 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6470_rot2_crop5.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6470_rot2_crop5.png 63 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6470_rot6_crop3.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6470_rot6_crop3.png 64 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6470_rot8_crop1.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6470_rot8_crop1.png 65 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6470_rot8_crop2.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6470_rot8_crop2.png 66 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6470_rot8_crop4.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6470_rot8_crop4.png 67 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6471_rot1_crop4.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6471_rot1_crop4.png 68 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6471_rot2_crop4.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6471_rot2_crop4.png 69 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6471_rot6_crop4.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6471_rot6_crop4.png 70 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6471_rot7_crop2.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6471_rot7_crop2.png 71 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6472_rot2_crop3.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6472_rot2_crop3.png 72 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6472_rot5_crop3.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6472_rot5_crop3.png 73 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6472_rot6_crop3.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6472_rot6_crop3.png 74 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6472_rot7_crop1.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6472_rot7_crop1.png 75 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6472_rot8_crop1.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6472_rot8_crop1.png 76 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6473_rot2_crop2.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6473_rot2_crop2.png 77 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6474_rot4_crop4.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6474_rot4_crop4.png 78 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6475_rot1_crop2.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6475_rot1_crop2.png 79 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6761_rot0_crop2.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6761_rot0_crop2.png 80 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6761_rot5_crop2.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6761_rot5_crop2.png 81 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6764_rot1_crop5.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6764_rot1_crop5.png 82 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6765_rot2_crop3.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6765_rot2_crop3.png 83 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6766_rot0_crop2.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6766_rot0_crop2.png 84 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6766_rot4_crop5.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6766_rot4_crop5.png 85 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6766_rot7_crop5.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6766_rot7_crop5.png 86 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6766_rot8_crop3.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6766_rot8_crop3.png 87 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6767_rot1_crop2.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6767_rot1_crop2.png 88 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6767_rot6_crop3.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6767_rot6_crop3.png 89 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6768_rot2_crop5.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6768_rot2_crop5.png 90 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6768_rot5_crop5.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6768_rot5_crop5.png 91 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6768_rot7_crop5.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6768_rot7_crop5.png 92 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6769_rot0_crop1.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6769_rot0_crop1.png 93 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6769_rot0_crop5.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6769_rot0_crop5.png 94 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6769_rot2_crop1.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6769_rot2_crop1.png 95 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6769_rot4_crop2.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6769_rot4_crop2.png 96 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6769_rot8_crop2.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6769_rot8_crop2.png 97 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6769_rot8_crop3.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6769_rot8_crop3.png 98 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6770_rot0_crop1.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6770_rot0_crop1.png 99 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6770_rot3_crop1.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6770_rot3_crop1.png 100 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6770_rot4_crop2.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6770_rot4_crop2.png 101 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6770_rot5_crop3.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6770_rot5_crop3.png 102 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6771_rot1_crop4.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6771_rot1_crop4.png 103 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6772_rot1_crop1.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6772_rot1_crop1.png 104 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6773_rot2_crop4.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6773_rot2_crop4.png 105 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6773_rot5_crop1.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6773_rot5_crop1.png 106 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6773_rot6_crop5.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6773_rot6_crop5.png 107 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6773_rot7_crop2.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6773_rot7_crop2.png 108 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6775_rot3_crop2.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6775_rot3_crop2.png 109 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6775_rot4_crop2.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6775_rot4_crop2.png 110 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6775_rot4_crop5.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6775_rot4_crop5.png 111 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6775_rot6_crop1.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6775_rot6_crop1.png 112 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6776_rot0_crop5.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6776_rot0_crop5.png 113 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6776_rot1_crop2.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6776_rot1_crop2.png 114 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6776_rot1_crop5.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6776_rot1_crop5.png 115 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6776_rot2_crop2.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6776_rot2_crop2.png 116 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6776_rot4_crop4.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6776_rot4_crop4.png 117 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6776_rot7_crop4.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6776_rot7_crop4.png 118 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6777_rot0_crop4.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6777_rot0_crop4.png 119 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6777_rot2_crop3.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6777_rot2_crop3.png 120 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6777_rot8_crop1.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6777_rot8_crop1.png 121 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6777_rot8_crop3.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6777_rot8_crop3.png 122 | /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_image/DSCN6777_rot8_crop4.jpg /home/yueyuanhao/deepcrack/data/CrackTree/crack_plus_test_mask/DSCN6777_rot8_crop4.png -------------------------------------------------------------------------------- /codes/model/111: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /codes/model/deepcrack.py: -------------------------------------------------------------------------------- 1 | from torch import nn 2 | import torch 3 | import torch.nn.functional as F 4 | 5 | 6 | def Conv3X3(in_, out): 7 | return torch.nn.Conv2d(in_, out, 3, padding=1) 8 | 9 | 10 | class ConvRelu(nn.Module): 11 | def __init__(self, in_, out): 12 | super().__init__() 13 | self.conv = Conv3X3(in_, out) 14 | self.activation = torch.nn.ReLU(inplace=True) 15 | 16 | def forward(self, x): 17 | x = self.conv(x) 18 | x = self.activation(x) 19 | return x 20 | 21 | class Down(nn.Module): 22 | 23 | def __init__(self, nn): 24 | super(Down,self).__init__() 25 | self.nn = nn 26 | self.maxpool_with_argmax = torch.nn.MaxPool2d(kernel_size=2, stride=2, return_indices=True) 27 | 28 | def forward(self,inputs): 29 | down = self.nn(inputs) 30 | unpooled_shape = down.size() 31 | outputs, indices = self.maxpool_with_argmax(down) 32 | return outputs, down, indices, unpooled_shape 33 | 34 | class Up(nn.Module): 35 | 36 | def __init__(self, nn): 37 | super().__init__() 38 | self.nn = nn 39 | self.unpool=torch.nn.MaxUnpool2d(2,2) 40 | 41 | def forward(self,inputs,indices,output_shape): 42 | outputs = self.unpool(inputs, indices=indices, output_size=output_shape) 43 | outputs = self.nn(outputs) 44 | return outputs 45 | 46 | class Fuse(nn.Module): 47 | 48 | def __init__(self, nn, scale): 49 | super().__init__() 50 | self.nn = nn 51 | self.scale = scale 52 | self.conv = Conv3X3(64,1) 53 | 54 | def forward(self,down_inp,up_inp): 55 | outputs = torch.cat([down_inp, up_inp], 1) 56 | outputs = F.interpolate(outputs, scale_factor=self.scale, mode='bilinear') 57 | outputs = self.nn(outputs) 58 | 59 | return self.conv(outputs) 60 | 61 | 62 | 63 | class DeepCrack(nn.Module): 64 | 65 | def __init__(self, num_classes=1000): 66 | super(DeepCrack, self).__init__() 67 | 68 | self.down1 = Down(torch.nn.Sequential( 69 | ConvRelu(3,64), 70 | ConvRelu(64,64), 71 | )) 72 | 73 | self.down2 = Down(torch.nn.Sequential( 74 | ConvRelu(64,128), 75 | ConvRelu(128,128), 76 | )) 77 | 78 | self.down3 = Down(torch.nn.Sequential( 79 | ConvRelu(128,256), 80 | ConvRelu(256,256), 81 | ConvRelu(256,256), 82 | )) 83 | 84 | self.down4 = Down(torch.nn.Sequential( 85 | ConvRelu(256, 512), 86 | ConvRelu(512, 512), 87 | ConvRelu(512, 512), 88 | )) 89 | 90 | self.down5 = Down(torch.nn.Sequential( 91 | ConvRelu(512, 512), 92 | ConvRelu(512, 512), 93 | ConvRelu(512, 512), 94 | )) 95 | 96 | self.up1 = Up(torch.nn.Sequential( 97 | ConvRelu(64, 64), 98 | ConvRelu(64, 64), 99 | )) 100 | 101 | self.up2 = Up(torch.nn.Sequential( 102 | ConvRelu(128, 128), 103 | ConvRelu(128, 64), 104 | )) 105 | 106 | self.up3 = Up(torch.nn.Sequential( 107 | ConvRelu(256, 256), 108 | ConvRelu(256, 256), 109 | ConvRelu(256, 128), 110 | )) 111 | 112 | self.up4 = Up(torch.nn.Sequential( 113 | ConvRelu(512, 512), 114 | ConvRelu(512, 512), 115 | ConvRelu(512, 256), 116 | )) 117 | 118 | self.up5 = Up(torch.nn.Sequential( 119 | ConvRelu(512, 512), 120 | ConvRelu(512, 512), 121 | ConvRelu(512, 512), 122 | )) 123 | 124 | self.fuse5 = Fuse(ConvRelu(512 + 512, 64), scale=16) 125 | self.fuse4 = Fuse(ConvRelu(512 + 256, 64), scale=8) 126 | self.fuse3 = Fuse(ConvRelu(256 + 128, 64), scale=4) 127 | self.fuse2 = Fuse(ConvRelu(128 + 64, 64), scale=2) 128 | self.fuse1 = Fuse(ConvRelu(64 + 64, 64), scale=1) 129 | 130 | self.final = Conv3X3(5,1) 131 | 132 | def forward(self,inputs): 133 | 134 | # encoder part 135 | out, down1, indices_1, unpool_shape1 = self.down1(inputs) 136 | out, down2, indices_2, unpool_shape2 = self.down2(out) 137 | out, down3, indices_3, unpool_shape3 = self.down3(out) 138 | out, down4, indices_4, unpool_shape4 = self.down4(out) 139 | out, down5, indices_5, unpool_shape5 = self.down5(out) 140 | 141 | # decoder part 142 | up5 = self.up5(out, indices=indices_5, output_shape=unpool_shape5) 143 | up4 = self.up4(up5, indices=indices_4, output_shape=unpool_shape4) 144 | up3 = self.up3(up4, indices=indices_3, output_shape=unpool_shape3) 145 | up2 = self.up2(up3, indices=indices_2, output_shape=unpool_shape2) 146 | up1 = self.up1(up2, indices=indices_1, output_shape=unpool_shape1) 147 | 148 | fuse5 = self.fuse5(down_inp=down5,up_inp=up5) 149 | fuse4 = self.fuse4(down_inp=down4, up_inp=up4) 150 | fuse3 = self.fuse3(down_inp=down3, up_inp=up3) 151 | fuse2 = self.fuse2(down_inp=down2, up_inp=up2) 152 | fuse1 = self.fuse1(down_inp=down1, up_inp=up1) 153 | 154 | output = self.final(torch.cat([fuse5,fuse4,fuse3,fuse2,fuse1],1)) 155 | 156 | return output, fuse5, fuse4, fuse3, fuse2, fuse1 157 | 158 | if __name__ == '__main__': 159 | inp = torch.randn((1,3,512,512)) 160 | 161 | model = DeepCrack() 162 | 163 | out = model(inp) 164 | 165 | -------------------------------------------------------------------------------- /codes/test.py: -------------------------------------------------------------------------------- 1 | from data.dataset import readIndex, dataReadPip, loadedDataset 2 | from model.deepcrack import DeepCrack 3 | from trainer import DeepCrackTrainer 4 | import cv2 5 | from tqdm import tqdm 6 | import numpy as np 7 | import torch 8 | import os 9 | 10 | os.environ["CUDA_VISIBLE_DEVICES"] = '0' 11 | 12 | 13 | def test(test_data_path='data/test_example.txt', 14 | save_path='deepcrack_results/', 15 | pretrained_model='checkpoints/DeepCrack_CT260_FT1.pth', ): 16 | if not os.path.exists(save_path): 17 | os.mkdir(save_path) 18 | 19 | test_pipline = dataReadPip(transforms=None) 20 | 21 | test_list = readIndex(test_data_path) 22 | 23 | test_dataset = loadedDataset(test_list, preprocess=test_pipline) 24 | 25 | test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=1, 26 | shuffle=False, num_workers=1, drop_last=False) 27 | 28 | # -------------------- build trainer --------------------- # 29 | 30 | device = torch.device("cuda") 31 | num_gpu = torch.cuda.device_count() 32 | 33 | model = DeepCrack() 34 | 35 | model = torch.nn.DataParallel(model, device_ids=range(num_gpu)) 36 | model.to(device) 37 | 38 | trainer = DeepCrackTrainer(model).to(device) 39 | 40 | model.load_state_dict(trainer.saver.load(pretrained_model, multi_gpu=True)) 41 | 42 | model.eval() 43 | 44 | with torch.no_grad(): 45 | for names, (img, lab) in tqdm(zip(test_list, test_loader)): 46 | test_data, test_target = img.type(torch.cuda.FloatTensor).to(device), lab.type(torch.cuda.FloatTensor).to( 47 | device) 48 | test_pred = trainer.val_op(test_data, test_target) 49 | test_pred = torch.sigmoid(test_pred[0].cpu().squeeze()) 50 | save_pred = torch.zeros((512 * 2, 512)) 51 | save_pred[:512, :] = test_pred 52 | save_pred[512:, :] = lab.cpu().squeeze() 53 | save_name = os.path.join(save_path, os.path.split(names[1])[1]) 54 | save_pred = save_pred.numpy() * 255 55 | cv2.imwrite(save_name, save_pred.astype(np.uint8)) 56 | 57 | 58 | if __name__ == '__main__': 59 | test() 60 | -------------------------------------------------------------------------------- /codes/tools/111: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /codes/tools/checkpointer.py: -------------------------------------------------------------------------------- 1 | import time 2 | import os 3 | from os import path 4 | import torch 5 | from tools.paths import process 6 | from queue import Queue 7 | 8 | 9 | class Checkpointer(object): 10 | r"""Checkpointer for objects using torch serialization. 11 | 12 | Args: 13 | name (str): Name of the checkpointer. This will also be used for 14 | the checkpoint filename. 15 | directory (str, optional): Parent directory of where the checkpoints will happen. 16 | A new sub-directory called checkpoints will be created (default '.') 17 | overwrite (bool, optional): Overwrite/remove the previous checkpoint (default True). 18 | verbose (bool, optional): Print a statement when loading a checkpoint (default True). 19 | timestamp (bool, optional): Add a timestamp to checkpoint filenames (default False). 20 | add_count (bool, optional): Add (zero-padded) counter to checkpoint filenames (default True). 21 | max_queue (int, optional): 22 | name format [name,_,tag,_,counter, _%Y-%m-%d-%H-%M-%S] 23 | 24 | """ 25 | 26 | def __init__(self, name, directory='.', overwrite=False, verbose=True, timestamp=False, add_count=True, 27 | max_queue=None): 28 | self.name = name 29 | self.directory = process(directory, create=True) 30 | self.directory = path.join(self.directory, 'checkpoints') 31 | self.directory = process(self.directory, create=True) 32 | self.overwrite = overwrite 33 | self.timestamp = timestamp 34 | self.add_count = add_count 35 | self.verbose = verbose 36 | self.chkp = path.join(self.directory, ".{0}.chkp".format(self.name)) 37 | self.counter, self.filename = torch.load(self.chkp) if path.exists(self.chkp) else (0, '') 38 | self.save_queue = False 39 | 40 | if overwrite == False and isinstance(max_queue, int) and max_queue > 1: 41 | self.save_queue = True 42 | self._queue = Queue(max_queue) 43 | elif max_queue is not None: 44 | print('WARNING: illegal max_queue Value!.') 45 | 46 | self.show_save_pth_name = '' 47 | 48 | def _say(self, line): 49 | if self.verbose: 50 | print(line) 51 | 52 | def _make_name(self, tag=None): 53 | strend = '' 54 | if tag is not None: 55 | strend += '_' + str(tag) 56 | if self.add_count: 57 | strend += "_{:07d}".format(self.counter) 58 | if self.timestamp: 59 | strend += time.strftime("_%Y-%m-%d-%H-%M-%S") 60 | filename = "{0}{1}.pth".format(self.name, strend) 61 | self.filename = path.join(self.directory, filename) 62 | return self.filename 63 | 64 | def _set_state(self, obj, state): 65 | if hasattr(obj, 'load_state_dict'): 66 | obj.load_state_dict(state) 67 | return obj 68 | else: 69 | return state 70 | 71 | def _get_state(self, obj): 72 | if isinstance(obj, torch.nn.DataParallel): 73 | obj = obj.module 74 | if hasattr(obj, 'state_dict'): 75 | return obj.state_dict() 76 | else: 77 | return obj 78 | 79 | def __call__(self, obj, tag=None, *args, **kwargs): 80 | """Same as :meth:`save`""" 81 | self.save(obj, tag=tag, *args, **kwargs) 82 | 83 | def save(self, obj, tag=None, *args, **kwargs): 84 | """Saves a checkpoint of an object. 85 | 86 | Args: 87 | obj: Object to save (must be serializable by torch). 88 | tag (str, optional): Tag to add to saved filename (default None). 89 | args: Arguments to pass to `torch.save`. 90 | kwargs: Keyword arguments to pass to `torch.save`. 91 | 92 | """ 93 | 94 | self.counter += 1 95 | old_filename = self.filename 96 | new_filename = self._make_name(tag) 97 | if self.save_queue is True: 98 | if self._queue.full() is True: 99 | delete_name = self._queue.get() 100 | try: 101 | os.remove(delete_name) 102 | except: 103 | pass 104 | self._queue.put(new_filename) 105 | 106 | if new_filename == old_filename and not self.overwrite: 107 | print('WARNING: Overwriting file in non overwrite mode.') 108 | elif self.overwrite: 109 | try: 110 | os.remove(old_filename) 111 | except: 112 | pass 113 | 114 | torch.save(self._get_state(obj), new_filename, *args, **kwargs) 115 | torch.save((self.counter, new_filename), self.chkp) 116 | 117 | self.show_save_pth_name = new_filename 118 | 119 | def load(self, obj=None, preprocess=None, multi_gpu=False, *args, **kwargs): 120 | """Loads a checkpoint from disk. 121 | 122 | Args: 123 | obj (optional): Needed if we load the `state_dict` of an `nn.Module`. 124 | preprocess (optional): Callable to preprocess the loaded object. 125 | args: Arguments to pass to `torch.load`. 126 | kwargs: Keyword arguments to pass to `torch.load`. 127 | 128 | Returns: 129 | The loaded file. 130 | 131 | """ 132 | if isinstance(obj, str) and obj.split('.')[-1] == 'pth': # 正常加载 133 | self._say("Loaded checkpoint: {0}".format(obj)) 134 | obj = torch.load(obj) 135 | elif self.counter > 0 and obj is None: 136 | loaded = torch.load(self.filename, *args, **kwargs) 137 | if preprocess is not None: 138 | loaded = preprocess(loaded) 139 | obj = self._set_state(obj, loaded) 140 | self._say("Loaded {0} checkpoint: {1}".format(self.name, self.filename)) 141 | 142 | if multi_gpu is True: 143 | from collections import OrderedDict 144 | multi_gpu_obj = OrderedDict() 145 | for k, v in obj.items(): 146 | name = 'module.' + k # add `module.` 147 | multi_gpu_obj[name] = v 148 | obj = multi_gpu_obj 149 | 150 | 151 | return obj 152 | 153 | 154 | -------------------------------------------------------------------------------- /codes/tools/paths.py: -------------------------------------------------------------------------------- 1 | import os 2 | from os import path 3 | from shutil import copyfile 4 | import errno 5 | 6 | __all__ = ['split', 'make', 'copy_to_dir', 'process', 'write_file'] 7 | 8 | 9 | def split(directory): 10 | """Splits a full filename path into its directory path, name and extension 11 | 12 | Args: 13 | directory (str): Directory to split. 14 | 15 | Returns: 16 | tuple: (Directory name, filename, extension) 17 | """ 18 | directory = process(directory) 19 | name, ext = path.splitext(path.basename(directory)) 20 | return path.dirname(directory), name, ext 21 | 22 | 23 | def make(directory): 24 | """Make a new directory 25 | 26 | Args: 27 | directory (str): Directory to make. 28 | """ 29 | try: 30 | os.makedirs(directory) 31 | except OSError as e: 32 | if e.errno != errno.EEXIST: 33 | raise 34 | 35 | 36 | def copy_to_dir(file, directory): 37 | """Copies a file to a directory 38 | 39 | Args: 40 | file (str): File to copy. 41 | directory (str): Directory to copy file to. 42 | """ 43 | file_path = path.join(directory, path.basename(file)) 44 | copyfile(file, file_path) 45 | 46 | 47 | def process(directory, create=False): 48 | """Expands home path, finds absolute path and creates directory (if create is True). 49 | 50 | Args: 51 | directory (str): Directory to process. 52 | create (bool, optional): If True, it creates the directory. 53 | 54 | Returns: 55 | str: The processed directory. 56 | """ 57 | directory = path.expanduser(directory) 58 | directory = path.normpath(directory) 59 | directory = path.abspath(directory) 60 | if create: 61 | make(directory) 62 | return directory 63 | 64 | 65 | def write_file(contents, filename, directory=".", append=False): 66 | """Writes contents to file. 67 | 68 | Args: 69 | contents (str): Contents to write to file. 70 | filename (str): File to write contents to. 71 | directory (str, optional): Directory to put file in. 72 | append (bool, optional): If True and file exists, it appends contents. 73 | 74 | Returns: 75 | str: Full path to file. 76 | """ 77 | full_name = path.join(process(directory), filename) 78 | mode = "a" if append else "w" 79 | with open(full_name, mode) as file_handle: 80 | file_handle.write(contents) 81 | return full_name 82 | -------------------------------------------------------------------------------- /codes/tools/visdom.py: -------------------------------------------------------------------------------- 1 | import visdom 2 | import numpy as np 3 | import time 4 | import torch 5 | import os 6 | 7 | 8 | class Visualizer(object): 9 | 10 | def __init__(self, env='default', **kwargs): 11 | self.env = env 12 | self.vis = visdom.Visdom(env=env, use_incoming_socket=False, **kwargs) 13 | self._vis_kwargs = kwargs 14 | 15 | self.index = {} 16 | self.log_text = {} 17 | 18 | def save_settings(self, save_path=None, save_log=False, save_img=False, save_plot=False): 19 | 20 | save_format = '{info}-{time}'.format(time=time.strftime("%Y-%m-%d %H:%M:%S"), info=self.env) 21 | self.save_path = os.path.join(save_path, save_format) 22 | 23 | if self.save_path and not os.path.exists(self.save_path): 24 | os.mkdir(self.save_path) 25 | 26 | self.save_log = save_log 27 | 28 | if self.save_path and self.save_log: 29 | os.mkdir((os.path.join(self.save_path, 'logs'))) 30 | 31 | self.save_img = save_img 32 | 33 | if self.save_path and self.save_img: 34 | os.mkdir((os.path.join(self.save_path, 'imgs'))) 35 | self.save_plot = save_plot 36 | 37 | if self.save_path and self.save_plot: 38 | os.mkdir((os.path.join(self.save_path, 'plots'))) 39 | 40 | def __getattr__(self, name): 41 | return getattr(self.vis, name) 42 | 43 | def reinit(self, env, **kwargs): 44 | self.vis = visdom.Visdom(env=env, **kwargs) 45 | 46 | def state_dict(self): 47 | return { 48 | 'index': self.index, 49 | 'log_text': self.log_text, 50 | '_vis_kwargs': self._vis_kwargs, 51 | 'env': self.vis.env, 52 | } 53 | 54 | def load_state_dict(self, d): 55 | self.vis = visdom.Visdom(env=d.get('env', self.vis.env), use_incoming_socket=False, **d.get('_vis_kwargs')) 56 | self.log_text = d.get('log_text', {}) 57 | self.index = d.get('index', {}) 58 | 59 | def log(self, info, win='defalut'): 60 | 61 | """ 62 | self.log({'loss':1,'lr':0.0001}, 'loss') 63 | self.log('start load dataset ...', 'info') 64 | self.log('acc TP:%f, FP:%f ....'%(a,b), 'acc') 65 | """ 66 | 67 | if self.log_text.get(win, None) is not None: 68 | flag = True 69 | else: 70 | flag = False 71 | 72 | self.log_text[win] = ('[{time}] {info}\n'.format(time=time.strftime("%Y-%m-%d %H:%M:%S"), info=info)) 73 | self.vis.text(self.log_text[win], win, append=flag) 74 | 75 | # if self.save_log: 76 | # with open(os.path.join(self.save_path, 'logs', '%s.txt'%win), 'a') as f: 77 | # f.write('%s'%(self.log_text[win])) 78 | 79 | def log_many(self, d): 80 | ''' 81 | d: dict{'loss':{'loss':1,'lr':0.0001}, 82 | 'info':'start load dataset ...' 83 | 'acc':'acc TP:%f, FP:%f ....'%(a,b)} 84 | ''' 85 | 86 | for k, v in d.items(): 87 | self.log(v, k) 88 | 89 | def img(self, img, win='default', **kwargs): 90 | ''' 91 | only tensor or numpy 92 | self.img(t.Tensor(64,64)) 93 | self.img(t.Tensor(3,64,64)) 94 | self.img('input_imgs',t.Tensor(100,1,64,64)) 95 | self.img('input_imgs',t.Tensor(100,3,64,64),nrows=10) 96 | ''' 97 | 98 | if torch.is_tensor(img): 99 | img = img.detach().cpu().numpy() 100 | self.vis.images(img, win=win, opts=dict(title=win), **kwargs) 101 | 102 | def img_many(self, d): 103 | for k, v in d.items(): 104 | self.img(v, k) 105 | 106 | def plot(self, y, win='loss', **kwargs): 107 | 108 | ''' 109 | 110 | :param y: scale float 111 | :param win: 112 | :param kwargs: 113 | :return: 114 | ''' 115 | x = self.index.get(win, 0) 116 | self.vis.line(Y=np.array([y]), X=np.array([x]), win=win, opts=dict(title=win), 117 | 118 | update=None if x == 0 else 'append', **kwargs) 119 | 120 | self.index[win] = x + 1 121 | 122 | def plot_many(self, d): 123 | """ 124 | plot multi values 125 | @params d: dict (name,value) i.e. ('loss',0.11) 126 | """ 127 | for k, v in d.items(): 128 | if v is not None: 129 | self.plot(v, k) 130 | -------------------------------------------------------------------------------- /codes/train.py: -------------------------------------------------------------------------------- 1 | from data.augmentation import augCompose, RandomBlur, RandomColorJitter 2 | from data.dataset import readIndex, dataReadPip, loadedDataset 3 | from tqdm import tqdm 4 | from model.deepcrack import DeepCrack 5 | from trainer import DeepCrackTrainer 6 | from config import Config as cfg 7 | import numpy as np 8 | import torch 9 | import os 10 | import cv2 11 | import sys 12 | 13 | os.environ["CUDA_VISIBLE_DEVICES"] = cfg.gpu_id 14 | 15 | 16 | def main(): 17 | # ----------------------- dataset ----------------------- # 18 | 19 | data_augment_op = augCompose(transforms=[[RandomColorJitter, 0.5], [RandomBlur, 0.2]]) 20 | 21 | train_pipline = dataReadPip(transforms=data_augment_op) 22 | 23 | test_pipline = dataReadPip(transforms=None) 24 | 25 | train_dataset = loadedDataset(readIndex(cfg.train_data_path, shuffle=True), preprocess=train_pipline) 26 | 27 | test_dataset = loadedDataset(readIndex(cfg.test_data_path), preprocess=test_pipline) 28 | 29 | train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=cfg.train_batch_size, 30 | shuffle=True, num_workers=4, drop_last=True) 31 | 32 | val_loader = torch.utils.data.DataLoader(test_dataset, batch_size=cfg.val_batch_size, 33 | shuffle=False, num_workers=4, drop_last=True) 34 | 35 | # -------------------- build trainer --------------------- # 36 | 37 | device = torch.device("cuda") 38 | num_gpu = torch.cuda.device_count() 39 | 40 | model = DeepCrack() 41 | model = torch.nn.DataParallel(model, device_ids=range(num_gpu)) 42 | model.to(device) 43 | 44 | trainer = DeepCrackTrainer(model).to(device) 45 | 46 | if cfg.pretrained_model: 47 | pretrained_dict = trainer.saver.load(cfg.pretrained_model, multi_gpu=True) 48 | model_dict = model.state_dict() 49 | 50 | pretrained_dict = {k: v for k, v in pretrained_dict.items() if k in model_dict} 51 | model_dict.update(pretrained_dict) 52 | model.load_state_dict(model_dict) 53 | trainer.vis.log('load checkpoint: %s' % cfg.pretrained_model, 'train info') 54 | 55 | try: 56 | 57 | for epoch in range(1, cfg.epoch): 58 | trainer.vis.log('Start Epoch %d ...' % epoch, 'train info') 59 | model.train() 60 | 61 | # --------------------- training ------------------- # 62 | bar = tqdm(enumerate(train_loader), total=len(train_loader)) 63 | bar.set_description('Epoch %d --- Training --- :' % epoch) 64 | for idx, (img, lab) in bar: 65 | data, target = img.type(torch.cuda.FloatTensor).to(device), lab.type(torch.cuda.FloatTensor).to(device) 66 | pred = trainer.train_op(data, target) 67 | if idx % cfg.vis_train_loss_every == 0: 68 | trainer.vis.log(trainer.log_loss, 'train_loss') 69 | trainer.vis.plot_many({ 70 | 'train_total_loss': trainer.log_loss['total_loss'], 71 | 'train_output_loss': trainer.log_loss['output_loss'], 72 | 'train_fuse5_loss': trainer.log_loss['fuse5_loss'], 73 | 'train_fuse4_loss': trainer.log_loss['fuse4_loss'], 74 | 'train_fuse3_loss': trainer.log_loss['fuse3_loss'], 75 | 'train_fuse2_loss': trainer.log_loss['fuse2_loss'], 76 | 'train_fuse1_loss': trainer.log_loss['fuse1_loss'], 77 | }) 78 | 79 | if idx % cfg.vis_train_acc_every == 0: 80 | trainer.acc_op(pred[0], target) 81 | trainer.vis.log(trainer.log_acc, 'train_acc') 82 | trainer.vis.plot_many({ 83 | 'train_mask_acc': trainer.log_acc['mask_acc'], 84 | 'train_mask_pos_acc': trainer.log_acc['mask_pos_acc'], 85 | 'train_mask_neg_acc': trainer.log_acc['mask_neg_acc'], 86 | }) 87 | if idx % cfg.vis_train_img_every == 0: 88 | trainer.vis.img_many({ 89 | 'train_img': data.cpu(), 90 | 'train_output': torch.sigmoid(pred[0].contiguous().cpu()), 91 | 'train_lab': target.unsqueeze(1).cpu(), 92 | 'train_fuse5': torch.sigmoid(pred[1].contiguous().cpu()), 93 | 'train_fuse4': torch.sigmoid(pred[2].contiguous().cpu()), 94 | 'train_fuse3': torch.sigmoid(pred[3].contiguous().cpu()), 95 | 'train_fuse2': torch.sigmoid(pred[4].contiguous().cpu()), 96 | 'train_fuse1': torch.sigmoid(pred[5].contiguous().cpu()), 97 | }) 98 | 99 | if idx % cfg.val_every == 0: 100 | trainer.vis.log('Start Val %d ....' % idx, 'train info') 101 | # -------------------- val ------------------- # 102 | model.eval() 103 | val_loss = { 104 | 'eval_total_loss': 0, 105 | 'eval_output_loss': 0, 106 | 'eval_fuse5_loss': 0, 107 | 'eval_fuse4_loss': 0, 108 | 'eval_fuse3_loss': 0, 109 | 'eval_fuse2_loss': 0, 110 | 'eval_fuse1_loss': 0, 111 | } 112 | val_acc = { 113 | 'mask_acc': 0, 114 | 'mask_pos_acc': 0, 115 | 'mask_neg_acc': 0, 116 | } 117 | 118 | bar.set_description('Epoch %d --- Evaluation --- :' % epoch) 119 | 120 | with torch.no_grad(): 121 | for idx, (img, lab) in enumerate(val_loader, start=1): 122 | val_data, val_target = img.type(torch.cuda.FloatTensor).to(device), lab.type( 123 | torch.cuda.FloatTensor).to(device) 124 | val_pred = trainer.val_op(val_data, val_target) 125 | trainer.acc_op(val_pred[0], val_target) 126 | val_loss['eval_total_loss'] += trainer.log_loss['total_loss'] 127 | val_loss['eval_output_loss'] += trainer.log_loss['output_loss'] 128 | val_loss['eval_fuse5_loss'] += trainer.log_loss['fuse5_loss'] 129 | val_loss['eval_fuse4_loss'] += trainer.log_loss['fuse4_loss'] 130 | val_loss['eval_fuse3_loss'] += trainer.log_loss['fuse3_loss'] 131 | val_loss['eval_fuse2_loss'] += trainer.log_loss['fuse2_loss'] 132 | val_loss['eval_fuse1_loss'] += trainer.log_loss['fuse1_loss'] 133 | val_acc['mask_acc'] += trainer.log_acc['mask_acc'] 134 | val_acc['mask_pos_acc'] += trainer.log_acc['mask_pos_acc'] 135 | val_acc['mask_neg_acc'] += trainer.log_acc['mask_neg_acc'] 136 | else: 137 | trainer.vis.img_many({ 138 | 'eval_img': val_data.cpu(), 139 | 'eval_output': torch.sigmoid(val_pred[0].contiguous().cpu()), 140 | 'eval_lab': val_target.unsqueeze(1).cpu(), 141 | 'eval_fuse5': torch.sigmoid(val_pred[1].contiguous().cpu()), 142 | 'eval_fuse4': torch.sigmoid(val_pred[2].contiguous().cpu()), 143 | 'eval_fuse3': torch.sigmoid(val_pred[3].contiguous().cpu()), 144 | 'eval_fuse2': torch.sigmoid(val_pred[4].contiguous().cpu()), 145 | 'eval_fuse1': torch.sigmoid(val_pred[5].contiguous().cpu()), 146 | 147 | }) 148 | trainer.vis.plot_many({ 149 | 'eval_total_loss': val_loss['eval_total_loss'] / idx, 150 | 'eval_output_loss': val_loss['eval_output_loss'] / idx, 151 | 'eval_fuse5_loss': val_loss['eval_fuse5_loss'] / idx, 152 | 'eval_fuse4_loss': val_loss['eval_fuse4_loss'] / idx, 153 | 'eval_fuse3_loss': val_loss['eval_fuse3_loss'] / idx, 154 | 'eval_fuse2_loss': val_loss['eval_fuse2_loss'] / idx, 155 | 'eval_fuse1_loss': val_loss['eval_fuse1_loss'] / idx, 156 | 157 | }) 158 | trainer.vis.plot_many({ 159 | 'eval_mask_acc': val_acc['mask_acc'] / idx, 160 | 'eval_mask_neg_acc': val_acc['mask_neg_acc'] / idx, 161 | 'eval_mask_pos_acc': val_acc['mask_pos_acc'] / idx, 162 | 163 | }) 164 | # ----------------- save model ---------------- # 165 | if cfg.save_pos_acc < (val_acc['mask_pos_acc'] / idx) and cfg.save_acc < ( 166 | val_acc['mask_acc'] / idx): 167 | cfg.save_pos_acc = (val_acc['mask_pos_acc'] / idx) 168 | cfg.save_acc = (val_acc['mask_acc'] / idx) 169 | trainer.saver.save(model, tag='%s_epoch(%d)_acc(%0.5f/%0.5f)' % ( 170 | cfg.name, epoch, cfg.save_pos_acc, cfg.save_acc)) 171 | trainer.vis.log('Save Model %s_epoch(%d)_acc(%0.5f/%0.5f)' % ( 172 | cfg.name, epoch, cfg.save_pos_acc, cfg.save_acc), 'train info') 173 | 174 | bar.set_description('Epoch %d --- Training --- :' % epoch) 175 | model.train() 176 | 177 | if epoch != 0: 178 | trainer.saver.save(model, tag='%s_epoch(%d)' % ( 179 | cfg.name, epoch)) 180 | trainer.vis.log('Save Model -%s_epoch(%d)' % ( 181 | cfg.name, epoch), 'train info') 182 | 183 | except KeyboardInterrupt: 184 | 185 | trainer.saver.save(model, tag='Auto_Save_Model') 186 | print('\n Catch KeyboardInterrupt, Auto Save final model : %s' % trainer.saver.show_save_pth_name) 187 | trainer.vis.log('Catch KeyboardInterrupt, Auto Save final model : %s' % trainer.saver.show_save_pth_name, 188 | 'train info') 189 | trainer.vis.log('Training End!!') 190 | try: 191 | sys.exit(0) 192 | except SystemExit: 193 | os._exit(0) 194 | 195 | 196 | if __name__ == '__main__': 197 | main() 198 | -------------------------------------------------------------------------------- /codes/trainer.py: -------------------------------------------------------------------------------- 1 | from torch import nn 2 | from tools.visdom import Visualizer 3 | from tools.checkpointer import Checkpointer 4 | from config import Config as cfg 5 | import torch 6 | 7 | 8 | def get_optimizer(model): 9 | if cfg.use_adam: 10 | return torch.optim.Adam(model.parameters(), lr=cfg.lr, weight_decay=cfg.weight_decay) 11 | else: 12 | return torch.optim.SGD(model.parameters(), lr=cfg.lr, weight_decay=cfg.weight_decay, momentum=cfg.momentum, ) 13 | 14 | 15 | class DeepCrackTrainer(nn.Module): 16 | def __init__(self, model): 17 | super(DeepCrackTrainer, self).__init__() 18 | self.vis = Visualizer(env=cfg.vis_env) 19 | self.model = model 20 | 21 | self.saver = Checkpointer(cfg.name, cfg.saver_path, overwrite=False, verbose=True, timestamp=True, 22 | max_queue=cfg.max_save) 23 | 24 | self.optimizer = get_optimizer(self.model) 25 | 26 | self.iter_counter = 0 27 | 28 | # -------------------- Loss --------------------- # 29 | 30 | self.mask_loss = nn.BCEWithLogitsLoss(reduction='mean', 31 | pos_weight=torch.cuda.FloatTensor([cfg.pos_pixel_weight])) 32 | 33 | self.log_loss = {} 34 | self.log_acc = {} 35 | 36 | def train_op(self, input, target): 37 | self.optimizer.zero_grad() 38 | 39 | pred_output, pred_fuse5, pred_fuse4, pred_fuse3, pred_fuse2, pred_fuse1, = self.model(input) 40 | 41 | output_loss = self.mask_loss(pred_output.view(-1, 1), target.view(-1, 1)) / cfg.train_batch_size 42 | fuse5_loss = self.mask_loss(pred_fuse5.view(-1, 1), target.view(-1, 1)) / cfg.train_batch_size 43 | fuse4_loss = self.mask_loss(pred_fuse4.view(-1, 1), target.view(-1, 1)) / cfg.train_batch_size 44 | fuse3_loss = self.mask_loss(pred_fuse3.view(-1, 1), target.view(-1, 1)) / cfg.train_batch_size 45 | fuse2_loss = self.mask_loss(pred_fuse2.view(-1, 1), target.view(-1, 1)) / cfg.train_batch_size 46 | fuse1_loss = self.mask_loss(pred_fuse1.view(-1, 1), target.view(-1, 1)) / cfg.train_batch_size 47 | 48 | total_loss = output_loss + fuse5_loss + fuse4_loss + fuse3_loss + fuse2_loss + fuse1_loss 49 | total_loss.backward() 50 | self.optimizer.step() 51 | 52 | self.iter_counter += 1 53 | 54 | self.log_loss = { 55 | 'total_loss': total_loss.item(), 56 | 'output_loss': output_loss.item(), 57 | 'fuse5_loss': fuse5_loss.item(), 58 | 'fuse4_loss': fuse4_loss.item(), 59 | 'fuse3_loss': fuse3_loss.item(), 60 | 'fuse2_loss': fuse2_loss.item(), 61 | 'fuse1_loss': fuse1_loss.item() 62 | } 63 | 64 | return pred_output, pred_fuse5, pred_fuse4, pred_fuse3, pred_fuse2, pred_fuse1, 65 | 66 | def val_op(self, input, target): 67 | pred_output, pred_fuse5, pred_fuse4, pred_fuse3, pred_fuse2, pred_fuse1, = self.model(input) 68 | 69 | output_loss = self.mask_loss(pred_output.view(-1, 1), target.view(-1, 1)) / cfg.train_batch_size 70 | fuse5_loss = self.mask_loss(pred_fuse5.view(-1, 1), target.view(-1, 1)) / cfg.train_batch_size 71 | fuse4_loss = self.mask_loss(pred_fuse4.view(-1, 1), target.view(-1, 1)) / cfg.train_batch_size 72 | fuse3_loss = self.mask_loss(pred_fuse3.view(-1, 1), target.view(-1, 1)) / cfg.train_batch_size 73 | fuse2_loss = self.mask_loss(pred_fuse2.view(-1, 1), target.view(-1, 1)) / cfg.train_batch_size 74 | fuse1_loss = self.mask_loss(pred_fuse1.view(-1, 1), target.view(-1, 1)) / cfg.train_batch_size 75 | 76 | total_loss = output_loss + fuse5_loss + fuse4_loss + fuse3_loss + fuse2_loss + fuse1_loss 77 | 78 | self.log_loss = { 79 | 'total_loss': total_loss.item(), 80 | 'output_loss': output_loss.item(), 81 | 'fuse5_loss': fuse5_loss.item(), 82 | 'fuse4_loss': fuse4_loss.item(), 83 | 'fuse3_loss': fuse3_loss.item(), 84 | 'fuse2_loss': fuse2_loss.item(), 85 | 'fuse1_loss': fuse1_loss.item() 86 | } 87 | 88 | return pred_output, pred_fuse5, pred_fuse4, pred_fuse3, pred_fuse2, pred_fuse1, 89 | 90 | def acc_op(self, pred, target): 91 | mask = target 92 | 93 | pred = pred 94 | pred[pred > cfg.acc_sigmoid_th] = 1 95 | pred[pred <= cfg.acc_sigmoid_th] = 0 96 | 97 | pred_mask = pred[:, 0, :, :].contiguous() 98 | 99 | mask_acc = pred_mask.eq(mask.view_as(pred_mask)).sum().item() / mask.numel() 100 | mask_pos_acc = pred_mask[mask > 0].eq(mask[mask > 0].view_as(pred_mask[mask > 0])).sum().item() / mask[ 101 | mask > 0].numel() 102 | mask_neg_acc = pred_mask[mask < 1].eq(mask[mask < 1].view_as(pred_mask[mask < 1])).sum().item() / mask[ 103 | mask < 1].numel() 104 | 105 | self.log_acc = { 106 | 'mask_acc': mask_acc, 107 | 'mask_pos_acc': mask_pos_acc, 108 | 'mask_neg_acc': mask_neg_acc, 109 | } 110 | -------------------------------------------------------------------------------- /figures/1000.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qinnzou/DeepCrack/f3988031dd2adc3d19b32d1c48a2bf90d12871ac/figures/1000.png -------------------------------------------------------------------------------- /figures/1014.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qinnzou/DeepCrack/f3988031dd2adc3d19b32d1c48a2bf90d12871ac/figures/1014.png -------------------------------------------------------------------------------- /figures/1022.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qinnzou/DeepCrack/f3988031dd2adc3d19b32d1c48a2bf90d12871ac/figures/1022.png -------------------------------------------------------------------------------- /figures/1042.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qinnzou/DeepCrack/f3988031dd2adc3d19b32d1c48a2bf90d12871ac/figures/1042.png -------------------------------------------------------------------------------- /figures/1045.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qinnzou/DeepCrack/f3988031dd2adc3d19b32d1c48a2bf90d12871ac/figures/1045.png -------------------------------------------------------------------------------- /figures/1065.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qinnzou/DeepCrack/f3988031dd2adc3d19b32d1c48a2bf90d12871ac/figures/1065.png -------------------------------------------------------------------------------- /figures/1095.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qinnzou/DeepCrack/f3988031dd2adc3d19b32d1c48a2bf90d12871ac/figures/1095.png -------------------------------------------------------------------------------- /figures/1096.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qinnzou/DeepCrack/f3988031dd2adc3d19b32d1c48a2bf90d12871ac/figures/1096.png -------------------------------------------------------------------------------- /figures/6192.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qinnzou/DeepCrack/f3988031dd2adc3d19b32d1c48a2bf90d12871ac/figures/6192.jpg -------------------------------------------------------------------------------- /figures/6207.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qinnzou/DeepCrack/f3988031dd2adc3d19b32d1c48a2bf90d12871ac/figures/6207.jpg -------------------------------------------------------------------------------- /figures/6264.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qinnzou/DeepCrack/f3988031dd2adc3d19b32d1c48a2bf90d12871ac/figures/6264.jpg -------------------------------------------------------------------------------- /figures/6328.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qinnzou/DeepCrack/f3988031dd2adc3d19b32d1c48a2bf90d12871ac/figures/6328.jpg -------------------------------------------------------------------------------- /figures/6750.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qinnzou/DeepCrack/f3988031dd2adc3d19b32d1c48a2bf90d12871ac/figures/6750.jpg -------------------------------------------------------------------------------- /figures/DSCN6428.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qinnzou/DeepCrack/f3988031dd2adc3d19b32d1c48a2bf90d12871ac/figures/DSCN6428.JPG -------------------------------------------------------------------------------- /figures/deepcrack-compare1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qinnzou/DeepCrack/f3988031dd2adc3d19b32d1c48a2bf90d12871ac/figures/deepcrack-compare1.png -------------------------------------------------------------------------------- /figures/deepcrack-compare2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qinnzou/DeepCrack/f3988031dd2adc3d19b32d1c48a2bf90d12871ac/figures/deepcrack-compare2.png -------------------------------------------------------------------------------- /figures/deepcrack-compare3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qinnzou/DeepCrack/f3988031dd2adc3d19b32d1c48a2bf90d12871ac/figures/deepcrack-compare3.png -------------------------------------------------------------------------------- /figures/fig: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /figures/intro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qinnzou/DeepCrack/f3988031dd2adc3d19b32d1c48a2bf90d12871ac/figures/intro.png -------------------------------------------------------------------------------- /figures/network.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qinnzou/DeepCrack/f3988031dd2adc3d19b32d1c48a2bf90d12871ac/figures/network.png --------------------------------------------------------------------------------