├── 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 | 
11 | # Some Results
12 | 
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 |
24 |
25 |
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 |
40 |
41 |
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 | 
78 | 
79 | 
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
--------------------------------------------------------------------------------