Reputation: 111
I have a satellite image and am trying to isolate one roof based on it's color. My plan is to take the color of a chosen point in the image, and create a slightly lighter > slightly darker range from it (allowing for variation based on sun and shade) and to remove all colors other than those within the range.
Then I need to keep only the color area that contains the originally selected point.
Below is an example sample image, color range and final image I would like to achieve edited manually in photoshop.
I have also had trouble converting an RGB color to HSV values that produce predictable results in the following script. I have tried following various guides for green-screening using python, e.g: this and this.
I have been trying to use the following but am running into a few issues:
img = cv2.imread("static.jpg".format(latlon, zoom))
img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# light color in RGB = [153, 139, 130]
# dark color in RGB = [82, 74, 71]
# How to convert these to HSV?
# using 150,0,0 here as it creates a valid range
hsv_color1 = np.array([150,0,0])
# using 180,255,255 here as it creates a valid range
hsv_color2 = np.array([180,255,255])
mask = cv2.inRange(img_hsv, hsv_color1, hsv_color2)
res = cv2.bitwise_and(img, img, mask = mask)
cv2.imshow('mask', mask)
cv2.imwrite("mask.jpg".format(latlon, zoom), mask)
cv2.imshow('img_hsv', img_hsv)
cv2.imwrite("img_hsv.jpg".format(latlon, zoom), img_hsv)
cv2.imshow('res', res)
cv2.imwrite("res.png".format(latlon, zoom), res)
So my 2 questions are:
I need to output an image that isolates the color area around a given pixel position.
Original
Desired Output
Light colour
Dark colour
Upvotes: 2
Views: 206
Reputation: 207345
Your dark value becomes 16/13/32 in HSV. And your light value becomes 23/14/60 in HSV.
OpenCV scales the Hue values by dividing by 2 so that the full range of 360 becomes 180 and still fits into an unsigned 8-bit number. So, you need to use a dark Hue value of 8 and a light Hue value of 12. I would widen that range by 3-5 at each end to allow some leeway, and use a lowish saturation to only pick up unsaturated, greyish values. So the code becomes:
#!/usr/bin/env python3
import cv2
import numpy as np
img = cv2.imread("static.jpg")
img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# light color in RGB = [153, 139, 130]
# dark color in RGB = [82, 74, 71]
hsv_lo = np.array([5,0,0])
hsv_hi = np.array([15,50,255])
mask = cv2.inRange(img_hsv, hsv_lo, hsv_hi)
res = cv2.bitwise_and(img, img, mask = mask)
cv2.imwrite("result.png", res)
Upvotes: 2