├── 2016_TITS_DNN__iter_200000.caffemodel ├── 2016_TITS_DNN__iter_200000.solverstate ├── Dataset Download ├── ICIP2016_Net_CV_4.prototxt ├── ICIP2016_Net_CV_4_solver.prototxt ├── README.md ├── deploy_crack.prototxt └── gen_crack_prob_map_multi_views_new.py /2016_TITS_DNN__iter_200000.caffemodel: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/larrycheungbai/ICIP2016_CNN_Crack_Detection/c40f555da3034bc6039f75b5701f9874d7ae79a6/2016_TITS_DNN__iter_200000.caffemodel -------------------------------------------------------------------------------- /2016_TITS_DNN__iter_200000.solverstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/larrycheungbai/ICIP2016_CNN_Crack_Detection/c40f555da3034bc6039f75b5701f9874d7ae79a6/2016_TITS_DNN__iter_200000.solverstate -------------------------------------------------------------------------------- /Dataset Download: -------------------------------------------------------------------------------- 1 | 2 | Thank you for your interesting. Please cite our paper. 3 | The dataset including patches for training and testing is on the cloud service provided by Baidu. 4 | Link: http://pan.baidu.com/s/1ckjR9G Password: du0q 5 | (链接:http://pan.baidu.com/s/1ckjR9G 密码:du0q) 6 | 7 | Google drive link: 8 | https://drive.google.com/open?id=0B4d93d_MPIxCSUFsYV9xbkVCcDQ 9 | -------------------------------------------------------------------------------- /ICIP2016_Net_CV_4.prototxt: -------------------------------------------------------------------------------- 1 | name: "Deep_Crack_Detection_CV_4" 2 | layers{ 3 | name: "ICIP2016" 4 | type: DATA 5 | top:"data" 6 | top:"label" 7 | data_param{ 8 | source: "2016_TITS_DNN_train_lmdb" 9 | #source: "train_fan" 10 | scale: 0.00390625 11 | batch_size: 48 12 | backend: LMDB 13 | } 14 | include: { phase: TRAIN } 15 | } 16 | layers{ 17 | name: "ICIP2016" 18 | type: DATA 19 | top:"data" 20 | top:"label" 21 | data_param{ 22 | #source: "2016_TITS_DNN_validation_lmdb" 23 | source: "auto_test_data_set_lmdb" 24 | scale: 0.00390625 25 | batch_size: 48 26 | backend: LMDB 27 | } 28 | include: { phase: TEST } 29 | } 30 | 31 | layers { 32 | name: "conv1" 33 | type: CONVOLUTION 34 | bottom: "data" 35 | top: "conv1" 36 | blobs_lr: 1 37 | blobs_lr: 2 38 | convolution_param { 39 | num_output: 48 40 | kernel_size: 4 41 | stride: 1 42 | weight_filler { 43 | type: "xavier" 44 | } 45 | bias_filler { 46 | type: "constant" 47 | } 48 | } 49 | } 50 | layers { 51 | name: "relu_c_1" 52 | type: RELU 53 | bottom: "conv1" 54 | top: "conv1" 55 | } 56 | layers { 57 | name: "pool1" 58 | type: POOLING 59 | bottom: "conv1" 60 | top: "pool1" 61 | pooling_param { 62 | pool: MAX 63 | kernel_size: 2 64 | stride: 2 65 | } 66 | } 67 | layers { 68 | name: "conv2" 69 | type: CONVOLUTION 70 | bottom: "pool1" 71 | top: "conv2" 72 | blobs_lr: 1 73 | blobs_lr: 2 74 | convolution_param { 75 | num_output: 48 76 | kernel_size: 5 77 | stride: 1 78 | weight_filler { 79 | type: "xavier" 80 | } 81 | bias_filler { 82 | type: "constant" 83 | } 84 | } 85 | } 86 | layers { 87 | name: "relu_c_2" 88 | type: RELU 89 | bottom: "conv2" 90 | top: "conv2" 91 | } 92 | layers { 93 | name: "pool2" 94 | type: POOLING 95 | bottom: "conv2" 96 | top: "pool2" 97 | pooling_param { 98 | pool: MAX 99 | kernel_size: 2 100 | stride: 2 101 | } 102 | } 103 | 104 | layers { 105 | name: "conv3" 106 | type: CONVOLUTION 107 | bottom: "pool2" 108 | top: "conv3" 109 | blobs_lr: 1 110 | blobs_lr: 2 111 | convolution_param { 112 | num_output: 48 113 | kernel_size: 3 114 | stride: 1 115 | weight_filler { 116 | type: "xavier" 117 | } 118 | bias_filler { 119 | type: "constant" 120 | } 121 | } 122 | } 123 | layers { 124 | name: "relu_c_3" 125 | type: RELU 126 | bottom: "conv3" 127 | top: "conv3" 128 | } 129 | layers { 130 | name: "pool3" 131 | type: POOLING 132 | bottom: "conv3" 133 | top: "pool3" 134 | pooling_param { 135 | pool: MAX 136 | kernel_size: 2 137 | stride: 2 138 | } 139 | } 140 | layers { 141 | name: "conv4" 142 | type: CONVOLUTION 143 | bottom: "pool3" 144 | top: "conv4" 145 | blobs_lr: 1 146 | blobs_lr: 2 147 | convolution_param { 148 | num_output: 48 149 | kernel_size: 4 150 | stride: 1 151 | weight_filler { 152 | type: "xavier" 153 | } 154 | bias_filler { 155 | type: "constant" 156 | } 157 | } 158 | } 159 | layers { 160 | name: "relu_c_4" 161 | type: RELU 162 | bottom: "conv4" 163 | top: "conv4" 164 | } 165 | 166 | layers { 167 | name: "pool4" 168 | type: POOLING 169 | bottom: "conv4" 170 | top: "pool4" 171 | pooling_param { 172 | pool: MAX 173 | kernel_size: 2 174 | stride: 2 175 | } 176 | } 177 | 178 | layers { 179 | name: "ip1" 180 | type: INNER_PRODUCT 181 | bottom: "pool4" 182 | top: "ip1" 183 | blobs_lr: 1 184 | blobs_lr: 2 185 | inner_product_param { 186 | num_output: 200 187 | weight_filler { 188 | type: "xavier" 189 | } 190 | bias_filler { 191 | type: "constant" 192 | } 193 | } 194 | } 195 | layers { 196 | name: "relu1" 197 | type: RELU 198 | bottom: "ip1" 199 | top: "ip1" 200 | } 201 | layer { 202 | name: "drop1" 203 | type: "Dropout" 204 | bottom: "ip1" 205 | top: "ip1" 206 | dropout_param { 207 | dropout_ratio: 0.5 208 | } 209 | } 210 | layers { 211 | name: "ip2" 212 | type: INNER_PRODUCT 213 | bottom: "ip1" 214 | top: "ip2" 215 | blobs_lr: 1 216 | blobs_lr: 2 217 | inner_product_param { 218 | num_output: 2 219 | weight_filler { 220 | type: "xavier" 221 | } 222 | bias_filler { 223 | type: "constant" 224 | } 225 | } 226 | } 227 | layers { 228 | name: "accuracy" 229 | type: ACCURACY 230 | bottom: "ip2" 231 | bottom: "label" 232 | top: "accuracy" 233 | include: { phase: TEST } 234 | } 235 | layers { 236 | name: "loss" 237 | type: SOFTMAX_LOSS 238 | bottom: "ip2" 239 | bottom: "label" 240 | top: "loss" 241 | } 242 | -------------------------------------------------------------------------------- /ICIP2016_Net_CV_4_solver.prototxt: -------------------------------------------------------------------------------- 1 | # The train/test net protocol buffer definition 2 | net: "ICIP2016_Net_CV_4.prototxt" 3 | #for test 4167 4 | #test_iter: 100 5 | #test_interval: 500 6 | # The base learning rate, momentum and the weight decay of the network. 7 | #0 to 80000 8 | #base_lr: 0.001 9 | # 80000 to 120000 10 | # base_lr: 0.0005 11 | # 120000 to 160000 12 | base_lr: 0.0001 13 | momentum: 0.9 14 | weight_decay: 0.0005 15 | # The learning rate policy 16 | lr_policy: "inv" 17 | gamma: 0.0001 18 | power: 0.75 19 | # Display every 100 iterations 20 | display: 100 21 | # The maximum number of iterations 22 | max_iter: 200000 23 | # snapshot intermediate results 24 | snapshot: 2000 25 | snapshot_prefix: "2016_TITS_DNN_" 26 | # solver mode: CPU or GPU 27 | solver_mode: GPU 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ICIP2016_CNN_Crack_Detection 2 | This is the resource for the paper "Road Crack Detection using Deep Convolutional Neural Network" 3 | 4 | If you find this project is helpful, please cite our papers: 5 | 6 | @inproceedings{zhang2016road, 7 | title={Road crack detection using deep convolutional neural network}, 8 | author={Zhang, Lei and Yang, Fan and Zhang, Yimin Daniel and Zhu, Ying Julie}, 9 | booktitle={2016 IEEE international conference on image processing (ICIP)}, 10 | pages={3708--3712}, 11 | year={2016}, 12 | organization={IEEE} 13 | } 14 | 15 | 16 | @article{xie2017deep, 17 | title={Deep learning in visual computing and signal processing}, 18 | author={Xie, Danfeng and Zhang, Lei and Bai, Li}, 19 | journal={Applied Computational Intelligence and Soft Computing}, 20 | volume={2017}, 21 | number={1}, 22 | pages={1320780}, 23 | year={2017}, 24 | publisher={Wiley Online Library} 25 | } 26 | 27 | @article{yang2019feature, 28 | title={Feature pyramid and hierarchical boosting network for pavement crack detection}, 29 | author={Yang, Fan and Zhang, Lei and Yu, Sijia and Prokhorov, Danil and Mei, Xue and Ling, Haibin}, 30 | journal={IEEE Transactions on Intelligent Transportation Systems}, 31 | volume={21}, 32 | number={4}, 33 | pages={1525--1535}, 34 | year={2019}, 35 | publisher={IEEE} 36 | } 37 | 38 | -------------------------------------------------------------------------------- /deploy_crack.prototxt: -------------------------------------------------------------------------------- 1 | name: "Deep_Crack_Detection_CV_4" 2 | input: "data" 3 | input_dim: 1 4 | input_dim: 3 5 | input_dim: 99 6 | input_dim: 99 7 | 8 | 9 | 10 | layer { 11 | name: "conv1" 12 | type: "Convolution" 13 | bottom: "data" 14 | top: "conv1" 15 | # blobs_lr: 1 16 | # blobs_lr: 2 17 | convolution_param { 18 | num_output: 48 19 | kernel_size: 4 20 | stride: 1 21 | # weight_filler { 22 | # type: "xavier" 23 | # } 24 | # bias_filler { 25 | # type: "constant" 26 | # } 27 | } 28 | } 29 | layer { 30 | name: "relu_c_1" 31 | type: "ReLU" 32 | bottom: "conv1" 33 | top: "conv1" 34 | } 35 | layer { 36 | name: "pool1" 37 | type: "Pooling" 38 | bottom: "conv1" 39 | top: "pool1" 40 | pooling_param { 41 | pool: MAX 42 | kernel_size: 2 43 | stride: 2 44 | } 45 | } 46 | layer { 47 | name: "conv2" 48 | type: "Convolution" 49 | bottom: "pool1" 50 | top: "conv2" 51 | # blobs_lr: 1 52 | # blobs_lr: 2 53 | convolution_param { 54 | num_output: 48 55 | kernel_size: 5 56 | stride: 1 57 | weight_filler { 58 | type: "xavier" 59 | } 60 | bias_filler { 61 | type: "constant" 62 | } 63 | } 64 | } 65 | layer { 66 | name: "relu_c_2" 67 | type: "ReLU" 68 | bottom: "conv2" 69 | top: "conv2" 70 | } 71 | layer { 72 | name: "pool2" 73 | type: "Pooling" 74 | bottom: "conv2" 75 | top: "pool2" 76 | pooling_param { 77 | pool: MAX 78 | kernel_size: 2 79 | stride: 2 80 | } 81 | } 82 | 83 | layer { 84 | name: "conv3" 85 | type: "Convolution" 86 | bottom: "pool2" 87 | top: "conv3" 88 | # blobs_lr: 1 89 | # blobs_lr: 2 90 | convolution_param { 91 | num_output: 48 92 | kernel_size: 3 93 | stride: 1 94 | weight_filler { 95 | type: "xavier" 96 | } 97 | bias_filler { 98 | type: "constant" 99 | } 100 | } 101 | } 102 | layer { 103 | name: "relu_c_3" 104 | type: "ReLU" 105 | bottom: "conv3" 106 | top: "conv3" 107 | } 108 | layer { 109 | name: "pool3" 110 | type: "Pooling" 111 | bottom: "conv3" 112 | top: "pool3" 113 | pooling_param { 114 | pool: MAX 115 | kernel_size: 2 116 | stride: 2 117 | } 118 | } 119 | layer { 120 | name: "conv4" 121 | type: "Convolution" 122 | bottom: "pool3" 123 | top: "conv4" 124 | # blobs_lr: 1 125 | # blobs_lr: 2 126 | convolution_param { 127 | num_output: 48 128 | kernel_size: 4 129 | stride: 1 130 | weight_filler { 131 | type: "xavier" 132 | } 133 | bias_filler { 134 | type: "constant" 135 | } 136 | } 137 | } 138 | layer { 139 | name: "relu_c_4" 140 | type: "ReLU" 141 | bottom: "conv4" 142 | top: "conv4" 143 | } 144 | 145 | layer { 146 | name: "pool4" 147 | type: "Pooling" 148 | bottom: "conv4" 149 | top: "pool4" 150 | pooling_param { 151 | pool: MAX 152 | kernel_size: 2 153 | stride: 2 154 | } 155 | } 156 | 157 | layer { 158 | name: "ip1" 159 | type: "InnerProduct" 160 | bottom: "pool4" 161 | top: "ip1" 162 | # blobs_lr: 1 163 | # blobs_lr: 2 164 | inner_product_param { 165 | num_output: 200 166 | weight_filler { 167 | type: "xavier" 168 | } 169 | bias_filler { 170 | type: "constant" 171 | } 172 | } 173 | } 174 | layer { 175 | name: "relu1" 176 | type: "ReLU" 177 | bottom: "ip1" 178 | top: "ip1" 179 | } 180 | layer { 181 | name: "drop1" 182 | type: "Dropout" 183 | bottom: "ip1" 184 | top: "ip1" 185 | dropout_param { 186 | dropout_ratio: 0.5 187 | } 188 | } 189 | layer { 190 | name: "ip2" 191 | type: "InnerProduct" 192 | bottom: "ip1" 193 | top: "ip2" 194 | # blobs_lr: 1 195 | # blobs_lr: 2 196 | inner_product_param { 197 | num_output: 2 198 | weight_filler { 199 | type: "xavier" 200 | } 201 | bias_filler { 202 | type: "constant" 203 | } 204 | } 205 | } 206 | 207 | layer { 208 | name: "prob" 209 | type: "Softmax" 210 | bottom: "ip2" 211 | top: "prob" 212 | } 213 | -------------------------------------------------------------------------------- /gen_crack_prob_map_multi_views_new.py: -------------------------------------------------------------------------------- 1 | # set up Python environment: numpy for numerical routines, and matplotlib for plotting 2 | import numpy as np 3 | import math as math 4 | import matplotlib.pyplot as plt 5 | from PIL import Image 6 | import sys 7 | caffe_root = '../../' # this file should be run from {caffe_root}/examples (otherwise change this line) 8 | sys.path.insert(0, caffe_root + 'python') 9 | import caffe 10 | # If you get "No module named _caffe", either you have not built pycaffe or you have the wrong path. 11 | import os 12 | #if os.path.isfile(caffe_root + 'models/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel'): 13 | caffe.set_mode_gpu() 14 | 15 | from skimage import data, io, filters, transform 16 | 17 | Polyp_root = '../' 18 | current_folder = '' 19 | if os.path.isfile(current_folder + '2016_TITS_DNN__iter_200000.caffemodel'): 20 | print 'Polyp network found.' 21 | else: 22 | print 'Need to Download pre-trained CaffeNet model...' 23 | exit() 24 | model_def = current_folder + 'deploy_crack.prototxt' 25 | model_weights = current_folder + '2016_TITS_DNN__iter_200000.caffemodel' 26 | net = caffe.Net(model_def, # defines the structure of the model 27 | model_weights, # contains the trained weights 28 | caffe.TEST) # use test mode (e.g., don't perform dropout) 29 | # create transformer for the input called 'data' 30 | transformer = caffe.io.Transformer({'data': net.blobs['data'].data.shape}) 31 | transformer.set_transpose('data', (2,0,1)) # move image channels to outermost dimension 32 | #transformer.set_mean('data', mu) # subtract the dataset-mean value in each channel 33 | #transformer.set_raw_scale('data', 255) # rescale from [0, 1] to [0, 255] 34 | transformer.set_channel_swap('data', (2,1,0)) # swap channels from RGB to BGR 35 | net.blobs['data'].reshape(1, # batch size 36 | 3, # 3-channel (BGR) images 37 | 99, 99) # image size is 99x99 38 | image = caffe.io.load_image('/home/lei/Downloads/caffe-master/data/PolypDetection/patches/ShortVD_wp_14_V2/ShortVD_wp_14_V2_frame_100_v_16_L_0.jpg') 39 | 40 | patient_dir = "/home/lei/Downloads/caffe-master/examples/previous_project/mirror_images/" 41 | for file in os.listdir(patient_dir): 42 | if file.endswith(".jpg") or file.endswith(".JPG") : 43 | print(file) 44 | image = caffe.io.load_image(patient_dir+file) 45 | (im_height, im_width, channels) = image.shape 46 | print im_width 47 | print im_height 48 | w = im_width 49 | h = im_height 50 | results_name = file[0:len(file)-4] 51 | final_results_name = results_name+'_DNN_result'+'.txt' 52 | fout = open(final_results_name,"w") 53 | for column in range(49,w-49): 54 | for row in range(49,h-49): 55 | # print column, row 56 | image_patch =image[row-49:row+50, column-49:column+50] 57 | # (im_height, im_width, channels) = image_patch.shape 58 | # print im_width, im_height 59 | transformed_image = transformer.preprocess('data', image_patch) 60 | net.blobs['data'].data[...] = transformed_image 61 | output = net.forward() 62 | output_prob_1 = output['prob'][0] 63 | pred_label_1 = output_prob_1.argmax() 64 | # print 'first', output_prob_1[0], output_prob_1[1],pred_label_1 65 | image_patch_2 = transform.rotate(image_patch,90) 66 | transformed_image = transformer.preprocess('data', image_patch_2) 67 | net.blobs['data'].data[...] = transformed_image 68 | output = net.forward() 69 | output_prob_2 = output['prob'][0] # the output probability vector for the first image in the batch 70 | pred_label_2 = output_prob_2.argmax() 71 | # print 'second', output_prob_2[0], output_prob_2[1],pred_label_2 72 | 73 | image_patch_3 = transform.rotate(image_patch,180) 74 | transformed_image = transformer.preprocess('data', image_patch_3) 75 | net.blobs['data'].data[...] = transformed_image 76 | output = net.forward() 77 | output_prob_3 = output['prob'][0] # the output probability vector for the first image in the batch 78 | pred_label_3 = output_prob_3.argmax() 79 | # print 'third', output_prob_3[0], output_prob_3[1],pred_label_3 80 | 81 | image_patch_4 = np.flipud(image_patch) 82 | transformed_image = transformer.preprocess('data', image_patch_4) 83 | net.blobs['data'].data[...] = transformed_image 84 | output = net.forward() 85 | output_prob_4 = output['prob'][0] # the output probability vector for the first image in the batch 86 | pred_label_4 = output_prob_4.argmax() 87 | # print 'forth', output_prob_4[0], output_prob_4[1],pred_label_4 88 | 89 | image_patch_5 = np.fliplr(image_patch) 90 | transformed_image = transformer.preprocess('data', image_patch_5) 91 | net.blobs['data'].data[...] = transformed_image 92 | output = net.forward() 93 | output_prob_5 = output['prob'][0] # the output probability vector for the first image in the batch 94 | pred_label_5 = output_prob_5.argmax() 95 | # print 'fifth', output_prob_5[0], output_prob_5[1],pred_label_5 96 | aggregated_prob = (output_prob_1[1] + output_prob_2[1] + output_prob_3[1] + output_prob_4[1] + output_prob_5[1]) / 5 97 | # print 'aggregate prob', aggregated_prob 98 | fout.write(str(aggregated_prob)+",") 99 | fout.write("\n") 100 | 101 | 102 | --------------------------------------------------------------------------------