Code Monkey home page Code Monkey logo

crack_segmentation's Introduction

Crack Segmentation

Here I present my solution to the problem crack segmentation for both pavement and concrete meterials. In this article, I describe the approaches, dataset that I exprimented with and desmonstrate the result. My approach is based on the UNet network with transfer learning on the two popular architectures: VGG16 and Resnet101. The result shows that a large crack segmentation dataset helps improve the performance of the model in diverse cases that could happen in practice.

Contents

Inference result preview

Below are the results from several test cases. For more test case results, please see images under the folder ./test_results

Overview

Crack segmentation is an important task in structure investigation problems. For example, in the bridge investigation project, a done is controlled to fly around bridges to take pictures of different bridge surfaces. The pictures will be then processed by computer to detect potential regions on the bridge surface that might be damaged. The more accurate the model is, the less human effort we need to process these images. Otherwise, the operators will have to check every single image, which is boring and error-prone. One challenge in this task is that the model is sentisive to noise and other objects such as moss on crack, title lines, etc. In this project, I tried to label over 300 high-resolution images from the crack dataset at my university and merged over 9 different segmentation crack datasets available on the Internet. The result show that the model could be able to distinguish crack from tree, title lines and other different noise in reality.

Dataset

From my knowledge, the dataset used in the project is the largest crack segmentation dataset so far. It contains around 11.200 images that are merged from 12 available crack segmentation datasets.

The name prefix of each image is assigned to the corresponding dataset name that the image belong to. There're also images with no crack pixel, which could be filtered out by the file name pattern "noncrack*"

All the images are resized to the size of (448, 448).

The two folders images and masks contain all the images. The two folders train and test contain training and testing images splitted from the two above folder. The splitting is stratified so that the proportion of each dataset in the train and test folder are similar


Dependencies

conda create --name crack
conda install -c anaconda pytorch-gpu 
conda install -c conda-forge opencv 
conda install matplotlib scipy numpy tqdm pillow

Inference

  • download the pre-trained model unet_vgg16 or unet_resnet_101.
  • put the downloaded model under the folder ./models
  • run the code
python inference_unet.py  -in_dir ./test_images -model_path ./models/model_unet_resnet_101_best.pt -out_dir ./test_result

Test Images Collection

The model works quite well in situations where there are just almost crack pixels and the concrete background in the images. However, it's often not the case in reality, where lots of different objects could simultenously show up in an image. Therefore, to evaluate the robustness of the crack model, I tried to come up with several cases that could happen in practice. These images could be found in the folder ./test_imgs in the same repository

  • pure crack: these are ideal cases where only crack objects occur in the images.
  • like crack: pictures of this type contains details that look like crack
  • crack with moss: there is moss on crack. These cases occur a lot in reality.
  • crack with noise: the background (wall, concrete) are lumpy
  • crack in large context: the context is large and diverse. For example, the whole house or street with people
pure crack like crack crack with moss
pure crack
no crack lumpy surface crack in large context

I am very welcome to further idea from you. please drop me an email at [email protected] if you think of other cases

Training

  • step 1. download the dataset from the link
  • step 2. run the training code
  • step 3:
python train_unet.py -data_dir PATH_TO_THE_DATASET_FOLDER -model_dir PATH_TO_MODEL_DIRECTORY -model_type resnet_101

Result

The best result is achieved by UNet_Resnet_101 with IoU = and Dice =

Model IOU Dice
UNet_VGG16 mean = 0.4687, std = 0.2217 mean = 0.6033, std = 0.2382
UNet_Resnet_101 mean = 0.3861, 0.2123 mean = 0.51877, std = 0.2538
DenseNet

Citation

Note: please cite the corresponding papers when using these datasets.

CRACK500:

@inproceedings{zhang2016road, title={Road crack detection using deep convolutional neural network}, author={Zhang, Lei and Yang, Fan and Zhang, Yimin Daniel and Zhu, Ying Julie}, booktitle={Image Processing (ICIP), 2016 IEEE International Conference on}, pages={3708--3712}, year={2016}, organization={IEEE} }' .

@article{yang2019feature, title={Feature Pyramid and Hierarchical Boosting Network for Pavement Crack Detection}, author={Yang, Fan and Zhang, Lei and Yu, Sijia and Prokhorov, Danil and Mei, Xue and Ling, Haibin}, journal={arXiv preprint arXiv:1901.06340}, year={2019} }

GAPs384:

@inproceedings{eisenbach2017how, title={How to Get Pavement Distress Detection Ready for Deep Learning? A Systematic Approach.}, author={Eisenbach, Markus and Stricker, Ronny and Seichter, Daniel and Amende, Karl and Debes, Klaus and Sesselmann, Maximilian and Ebersbach, Dirk and Stoeckert, Ulrike and Gross, Horst-Michael}, booktitle={International Joint Conference on Neural Networks (IJCNN)}, pages={2039--2047}, year={2017} }

CFD:

@article{shi2016automatic, title={Automatic road crack detection using random structured forests}, author={Shi, Yong and Cui, Limeng and Qi, Zhiquan and Meng, Fan and Chen, Zhensong}, journal={IEEE Transactions on Intelligent Transportation Systems}, volume={17}, number={12}, pages={3434--3445}, year={2016}, publisher={IEEE} }

AEL:

@article{amhaz2016automatic, title={Automatic Crack Detection on Two-Dimensional Pavement Images: An Algorithm Based on Minimal Path Selection.}, author={Amhaz, Rabih and Chambon, Sylvie and Idier, J{'e}r{^o}me and Baltazart, Vincent} }

cracktree200:

@article{zou2012cracktree, title={CrackTree: Automatic crack detection from pavement images}, author={Zou, Qin and Cao, Yu and Li, Qingquan and Mao, Qingzhou and Wang, Song}, journal={Pattern Recognition Letters}, volume={33}, number={3}, pages={227--238}, year={2012}, publisher={Elsevier} }

https://github.com/alexdonchuk/cracks_segmentation_dataset

https://github.com/yhlleo/DeepCrack

https://github.com/ccny-ros-pkg/concreteIn_inpection_VGGF

crack_segmentation's People

Contributors

khanhha avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

crack_segmentation's Issues

the pretrained weight of resnet is invalid

I want to cite your work on github in my paper related to UAV bridge inspection, but the weight of the pretrained weight of resnet is invalid, please check it on your github so that I can cite your work, thanks!

Code license

Hi khanhha,

I'm a developer working on my open-sourced projects and I found that your github repo crack_segmentation very useful! Thanks a lot for your contribution to the open-sourced community!

By the way, would you mind adding a license such as MIT license to your github repository? This kind of license will confirm the open sourced usage of this repo and perhaps more people will use it without any license problem.

I’m looking forward to your reply and thanks by advance.

Best,
xcqiutim

Mask creation tool

Hi khanhha,

thanks for providing this dataset. This is really fantastic.
How did you produce the masks for the images?
Which tool did you use ... I only found annotation-tools that can to polyline or rectangles. But it seems that you have really hand-drawn the cracks?

Thanks for any help
Stefan

Crack mask is much more wider than the real crack

    Thank you very much for your sharing! Datasets about crack are really hard to find. But i've found out that some crack mask in dataset are much more wider than the real crack, let's take Volker_DSC01704_219_142_1156_1117.jpg in this dataset as example, crack width in the mask is about 10 pixels, while the real crack width is about 2 or 3 pixel width. 
    Is crack label width 3 times larger than the crack 's real width? I think mismatch crack width would effect the segmentation model' s performance, as the BCE loss would take crack pixel gray value into account, and i don't know how to generate accurate crack pixel width based on these wider masks
   Any advice or suggestions would be appreciated! Thank you again!

in the utils.py

in line number 30
use this code to fix it

def cuda(x):
return x.cuda(non_blocking=True) if torch.cuda.is_available() else x

Bro in the code their is problem

use this for inference :-
python inference_unet.py -img_dir ./test_images -model_path ./model.pth -model_type resnet101 -out_viz_dir ./viz_result -out_pred_dir ./pred_result -threshold 0.5

Have you encountered this problem?Thanks to answer

Traceback (most recent call last):
File "/environment/python/versions/miniconda3-4.7.12/lib/python3.7/site-packages/visdom/init.py", line 711, in _send
data=json.dumps(msg),
File "/environment/python/versions/miniconda3-4.7.12/lib/python3.7/site-packages/visdom/init.py", line 677, in _handle_post
r = self.session.post(url, data=data)
File "/environment/python/versions/miniconda3-4.7.12/lib/python3.7/site-packages/requests/sessions.py", line 578, in post
return self.request('POST', url, data=data, json=json, **kwargs)
File "/environment/python/versions/miniconda3-4.7.12/lib/python3.7/site-packages/requests/sessions.py", line 530, in request
resp = self.send(prep, **send_kwargs)
File "/environment/python/versions/miniconda3-4.7.12/lib/python3.7/site-packages/requests/sessions.py", line 643, in send
r = adapter.send(request, **kwargs)
File "/environment/python/versions/miniconda3-4.7.12/lib/python3.7/site-packages/requests/adapters.py", line 510, in send
raise ProxyError(e, request=request)
requests.exceptions.ProxyError: HTTPConnectionPool(host='127.0.0.1', port=7890): Max retries exceeded with url: http://localhost:8097/events (Caused by ProxyError('Cannot connect to proxy.', RemoteDisconnected('Remote end closed connection without response')))
item ['/home/featurize/data/DeepCrack-datasets/CrackTree260/CrackTree260/6192.jpg', '/home/featurize/data/DeepCrack-datasets/CrackTree260/CrackTree260_gt/6192.bmp']
item ['/home/featurize/data/DeepCrack-datasets/CrackTree260/CrackTree260/6219.jpg', '/home/featurize/data/DeepCrack-datasets/CrackTree260/CrackTree260_gt/6219.bmp']
item ['/home/featurize/data/DeepCrack-datasets/CrackTree260/CrackTree260/6221.jpg', '/home/featurize/data/DeepCrack-datasets/CrackTree260/CrackTree260_gt/6221.bmp']
item ['/home/featurize/data/DeepCrack-datasets/CrackTree260/CrackTree260/6225.jpg', '/home/featurize/data/DeepCrack-datasets/CrackTree260/CrackTree260_gt/6225.bmp']
0%| | 0/39 [00:00<?, ?it/s]bar 0%| | 0/39 [00:00<?, ?it/s]
Epoch 1 --- Training --- :: 0%| | 0/39 [00:00<?, ?it/s]item ['/home/featurize/data/DeepCrack-datasets/CrackTree260/CrackTree260/6194.jpg', '/home/featurize/data/DeepCrack-datasets/CrackTree260/CrackTree260_gt/6194.bmp']
item ['/home/featurize/data/DeepCrack-datasets/CrackTree260/CrackTree260/6220.jpg', '/home/featurize/data/DeepCrack-datasets/CrackTree260/CrackTree260_gt/6220.bmp']
item ['/home/featurize/data/DeepCrack-datasets/CrackTree260/CrackTree260/6229.jpg', '/home/featurize/data/DeepCrack-datasets/CrackTree260/CrackTree260_gt/6229.bmp']
item ['/home/featurize/data/DeepCrack-datasets/CrackTree260/CrackTree260/6228.jpg', '/home/featurize/data/DeepCrack-datasets/CrackTree260/CrackTree260_gt/6228.bmp']
item ['/home/featurize/data/DeepCrack-datasets/CrackTree260/CrackTree260/6206.jpg', '/home/featurize/data/DeepCrack-datasets/CrackTree260/CrackTree260_gt/6206.bmp']
/environment/python/versions/miniconda3-4.7.12/lib/python3.7/site-packages/torch/nn/functional.py:693: UserWarning: Named tensors and all their associated APIs are an experimental feature and subject to change. Please do not use them for anything important until they are released as stable. (Triggered internally at /pytorch/c10/core/TensorImpl.h:1156.)
return torch._C._nn.max_pool2d_with_indices(input, kernel_size, stride, padding, dilation, ceil_mode)
/environment/python/versions/miniconda3-4.7.12/lib/python3.7/site-packages/torch/nn/functional.py:3613: UserWarning: Default upsampling behavior when mode=bilinear is changed to align_corners=False since 0.4.0. Please specify align_corners=True if the old behavior is desired. See the documentation of nn.Upsample for details.
"See the documentation of nn.Upsample for details.".format(mode)
Epoch 1 --- Training --- :: 0%| | 0/39 [00:00<?, ?it/s]
Traceback (most recent call last):
File "train.py", line 198, in
main()
File "train.py", line 67, in main
pred = trainer.train_op(data, target)
File "/cloud/DeepCrack-master/codes/trainer.py", line 39, in train_op
pred_output, pred_fuse5, pred_fuse4, pred_fuse3, pred_fuse2, pred_fuse1 = self.model(input)
File "/environment/python/versions/miniconda3-4.7.12/lib/python3.7/site-packages/torch/nn/modules/module.py", line 1051, in _call_impl
return forward_call(*input, **kwargs)
File "/environment/python/versions/miniconda3-4.7.12/lib/python3.7/site-packages/torch/nn/parallel/data_parallel.py", line 166, in forward
return self.module(*inputs[0], **kwargs[0])
File "/environment/python/versions/miniconda3-4.7.12/lib/python3.7/site-packages/torch/nn/modules/module.py", line 1051, in _call_impl
return forward_call(*input, **kwargs)
File "/cloud/DeepCrack-master/codes/model/deepcrack.py", line 154, in forward
output = self.final(torch.cat([fuse5,fuse4,fuse3,fuse2,fuse1],1))
RuntimeError: Sizes of tensors must match except in dimension 2. Got 600 and 592 (The offending index is 0)

where is the joint_transforms

When I was reading train_tiramisu.py, I found that the code need to import JointRandomSizedCrop from joint_transforms.
However, I did not find the joint_transforms. Whether it is a package, or you deleted it?

where is unet_resnet_101

Hi, I would like to try [unet_resnet_101], but the link provided in README is not available.
@khanhha Coul you please upload it again? Thank you so much.

Patchwise inference in unet_inference.py

Hi @khanhha , thanks for the repo and the pretrained model. I note in inference_unet.py that you perform once inference on the entire image and then on patches of images and then merge the patches to form the final picture.

N typically the patch-based inference performs better. Is there any reason you took the patch-based approach?

Hi

Would it be possible to share the training dataset you used? I saw you reckoned that you were using the largest crack segmentation dataset available. It would be super helpful to have a link of those dataset or links if they are not combined already.
Thanks and looking forward to your response.

Model not training with resnet101 and resnet34

When I am trying to train the model with resnet101, I am getting the following error. Please help me figure this out.

0%| | 0/14848 [00:00<?, ?it/s]
Epoch 0: 0%| | 0/14848 [00:00<?, ?it/s]total images = 17469
create resnet101 model
Started training model from epoch 0
Traceback (most recent call last):
File "train_unet.py", line 251, in
train(train_loader, model, criterion, optimizer, validate, args)
File "train_unet.py", line 118, in train
masks_pred = model(input_var)
File "/opt/apps/Anaconda3/2019.03/envs/powerai16_ibm/lib/python3.6/site-packages/torch/nn/modules/module.py", line 489, in call
result = self.forward(*input, **kwargs)
File "/home/nys09/unet/unet_transfer.py", line 233, in forward
dec5 = self.dec5(torch.cat([center, conv5], 1))
RuntimeError: invalid argument 0: Sizes of tensors must match except in dimension 1. Got 7 and 6 in dimension 2 at /opt/anaconda/conda-bld/pytorch_1551416914958/work/aten/src/THC/generic/THCTensorMath.cu:83

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.