Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Detection of rust with OpenCV (Python)

We are currently working on a project whereby we have to detect rust on a building by taking pictures (using a drone). We then plan to use OpenCV to detect the colour of rust (brownish-orange) from the photographs taken.

However, we are facing difficulties with the color detection whereby other shades of color (yellow) are being detected as well and also not all shades of rust are being detected. So how can we solve this problem?

This is the link that we are using as guidance for our rust detection procedure: Colour Detection

This is the photograph that we want to detect rust: Rust Image

So this is the 1st version of our code, we selected the lightest and darkest shade of rust using GIMP and we set the BGR as our boundaries as shown in the code:

import cv2 
import numpy as np

#Read the Rust Photograph
img = cv2.imread('/home/brendanloe/Downloads/img.jpeg', 1)

#Set the boundary for the shade of rust 
boundaries = [ ([58, 57, 101], [76, 95, 162]) ]

#Highlight out the shade of rust
for (lower, upper) in boundaries:
    lower = np.array(lower, dtype = "uint8")
    upper = np.array(upper, dtype = "uint8")
    mask = cv2.inRange(img, lower, upper)
    output = cv2.bitwise_and(img, img, mask = mask)

#Show the shade of rust that is highlighted
cv2.imshow("images", np.hstack([img, output]))
cv2.waitKey(0)

Here is the result after running the code: Result 1

Hence we decided to come up with a 2nd version, with more boundaries for the shades of rust which couldn't be captured from the 1st version:

import cv2
import numpy as np

#Read the Rust Photograph
img = cv2.imread('/home/brendanloe/Downloads/img.jpeg', 1)

#Set different boundaries for different shades of rust
boundaries1 = [ ([58, 57, 101], [76, 95, 162]) ]
boundaries2 = [ ([26, 61, 111], [81, 144, 202]) ]
boundaries3 = [ ([44, 102, 167], [115, 169, 210]) ]

#Highlight out the shades of rust
for (lower1, upper1) in boundaries1:
    lower1 = np.array(lower1, dtype = "uint8")
    upper1 = np.array(upper1, dtype = "uint8")
    mask = cv2.inRange(img, lower1, upper1)
    output1 = cv2.bitwise_and(img, img, mask = mask)

for (lower2, upper2) in boundaries2:
    lower2 = np.array(lower2, dtype = "uint8")
    upper2 = np.array(upper2, dtype = "uint8")
    mask = cv2.inRange(img, lower2, upper2)
    output2 = cv2.bitwise_and(img, img, mask = mask)

for (lower3, upper3) in boundaries3:
    lower3 = np.array(lower3, dtype = "uint8")
    upper3 = np.array(upper3, dtype = "uint8")
    mask = cv2.inRange(img, lower3, upper3)
    output3 = cv2.bitwise_and(img, img, mask = mask)

#Combine the 3 different masks with the different shades into 1 image file
final = cv2.bitwise_or(output1, output2, output3)
cv2.imshow("final", final)
cv2.waitKey(0)

Here is the result after running the 2nd version of the code: Result 2

With the 2nd version, we were able to capture more shades of rust. However, not all the shades of rust were fully captured and the surroundings like trees and "parking" painting on the ground were captured as well.

Ideally, we want to program in a way where opencv automatically detect the rust when different photos of rust are opened, and also not to detect unwanted colors like our example as stated above.

Thank you for the help in advance.

Detection of rust with OpenCV (Python)

We are currently working on a project whereby we have to detect rust on a building by taking pictures (using a drone). We then plan to use OpenCV to detect the colour of rust (brownish-orange) from the photographs taken.

However, we are facing difficulties with the color detection whereby other shades of color (yellow) are being detected as well and also not all shades of rust are being detected. So how can we solve this problem?

This is the link that we are using as guidance for our rust detection procedure: Colour DetectionColour Detection

This is the photograph that we want to detect rust: Rust ImageRust Image

So this is the 1st version of our code, we selected the lightest and darkest shade of rust using GIMP and we set the BGR as our boundaries as shown in the code:

import cv2 
import numpy as np

#Read the Rust Photograph
img = cv2.imread('/home/brendanloe/Downloads/img.jpeg', 1)

#Set the boundary for the shade of rust 
boundaries = [ ([58, 57, 101], [76, 95, 162]) ]

#Highlight out the shade of rust
for (lower, upper) in boundaries:
    lower = np.array(lower, dtype = "uint8")
    upper = np.array(upper, dtype = "uint8")
    mask = cv2.inRange(img, lower, upper)
    output = cv2.bitwise_and(img, img, mask = mask)

#Show the shade of rust that is highlighted
cv2.imshow("images", np.hstack([img, output]))
cv2.waitKey(0)

Here is the result after running the code: Result 1Result 1

Hence we decided to come up with a 2nd version, with more boundaries for the shades of rust which couldn't be captured from the 1st version:

import cv2
import numpy as np

#Read the Rust Photograph
img = cv2.imread('/home/brendanloe/Downloads/img.jpeg', 1)

#Set different boundaries for different shades of rust
boundaries1 = [ ([58, 57, 101], [76, 95, 162]) ]
boundaries2 = [ ([26, 61, 111], [81, 144, 202]) ]
boundaries3 = [ ([44, 102, 167], [115, 169, 210]) ]

#Highlight out the shades of rust
for (lower1, upper1) in boundaries1:
    lower1 = np.array(lower1, dtype = "uint8")
    upper1 = np.array(upper1, dtype = "uint8")
    mask = cv2.inRange(img, lower1, upper1)
    output1 = cv2.bitwise_and(img, img, mask = mask)

for (lower2, upper2) in boundaries2:
    lower2 = np.array(lower2, dtype = "uint8")
    upper2 = np.array(upper2, dtype = "uint8")
    mask = cv2.inRange(img, lower2, upper2)
    output2 = cv2.bitwise_and(img, img, mask = mask)

for (lower3, upper3) in boundaries3:
    lower3 = np.array(lower3, dtype = "uint8")
    upper3 = np.array(upper3, dtype = "uint8")
    mask = cv2.inRange(img, lower3, upper3)
    output3 = cv2.bitwise_and(img, img, mask = mask)

#Combine the 3 different masks with the different shades into 1 image file
final = cv2.bitwise_or(output1, output2, output3)
cv2.imshow("final", final)
cv2.waitKey(0)

Here is the result after running the 2nd version of the code: Result 2Result 2

With the 2nd version, we were able to capture more shades of rust. However, not all the shades of rust were fully captured and the surroundings like trees and "parking" painting on the ground were captured as well.

Ideally, we want to program in a way where opencv automatically detect the rust when different photos of rust are opened, and also not to detect unwanted colors like our example as stated above.

Thank you for the help in advance.

Detection of rust with OpenCV (Python)

We are currently working on a project whereby we have to detect rust on a building by taking pictures (using a drone). We then plan to use OpenCV to detect the colour of rust (brownish-orange) from the photographs taken.

However, we are facing difficulties with the color detection whereby other shades of color (yellow) are being detected as well and also not all shades of rust are being detected. So how can we solve this problem?

This is the link that we are using as guidance for our rust detection procedure: Colour DetectionColour Detection

This is the photograph that we want to detect rust: Rust ImageRust Image

So this is the 1st version of our code, we selected the lightest and darkest shade of rust using GIMP and we set the BGR as our boundaries as shown in the code:

import cv2 
import numpy as np

#Read the Rust Photograph
img = cv2.imread('/home/brendanloe/Downloads/img.jpeg', 1)

#Set the boundary for the shade of rust 
boundaries = [ ([58, 57, 101], [76, 95, 162]) ]

#Highlight out the shade of rust
for (lower, upper) in boundaries:
    lower = np.array(lower, dtype = "uint8")
    upper = np.array(upper, dtype = "uint8")
    mask = cv2.inRange(img, lower, upper)
    output = cv2.bitwise_and(img, img, mask = mask)

#Show the shade of rust that is highlighted
cv2.imshow("images", np.hstack([img, output]))
cv2.waitKey(0)

Here is the result after running the code: Result 1

Hence we decided to come up with a 2nd version, with more boundaries for the shades of rust which couldn't be captured from the 1st version:

import cv2
import numpy as np

#Read the Rust Photograph
img = cv2.imread('/home/brendanloe/Downloads/img.jpeg', 1)

#Set different boundaries for different shades of rust
boundaries1 = [ ([58, 57, 101], [76, 95, 162]) ]
boundaries2 = [ ([26, 61, 111], [81, 144, 202]) ]
boundaries3 = [ ([44, 102, 167], [115, 169, 210]) ]

#Highlight out the shades of rust
for (lower1, upper1) in boundaries1:
    lower1 = np.array(lower1, dtype = "uint8")
    upper1 = np.array(upper1, dtype = "uint8")
    mask = cv2.inRange(img, lower1, upper1)
    output1 = cv2.bitwise_and(img, img, mask = mask)

for (lower2, upper2) in boundaries2:
    lower2 = np.array(lower2, dtype = "uint8")
    upper2 = np.array(upper2, dtype = "uint8")
    mask = cv2.inRange(img, lower2, upper2)
    output2 = cv2.bitwise_and(img, img, mask = mask)

for (lower3, upper3) in boundaries3:
    lower3 = np.array(lower3, dtype = "uint8")
    upper3 = np.array(upper3, dtype = "uint8")
    mask = cv2.inRange(img, lower3, upper3)
    output3 = cv2.bitwise_and(img, img, mask = mask)

#Combine the 3 different masks with the different shades into 1 image file
final = cv2.bitwise_or(output1, output2, output3)
cv2.imshow("final", final)
cv2.waitKey(0)

Here is the result after running the 2nd version of the code: Result 2

With the 2nd version, we were able to capture more shades of rust. However, not all the shades of rust were fully captured and the surroundings like trees and "parking" painting on the ground were captured as well.

Ideally, we want to program in a way where opencv automatically detect the rust when different photos of rust are opened, and also not to detect unwanted colors like our example as stated above.

Thank you for the help in advance.