python 2.7 - How can i find the pixel color range in an image that excludes outliers? -
i have code randomly generates 10 pixel locations in image dimensions. want take each pixel location , find gbr value , find largest g value, b value, r value , smallest g value b value , r value. found code can take color boundaries , create mask image. might want incorporate mean g, b , r value , compute standard deviation each , use eliminate outliers.
or instead of using code wrote generate 10 random pixels if there way color range inside of +- 1 standard deviation of mean color of image?
see code below:
import cv2 import numpy np import random name = "highway" img = cv2.imread(name + ".jpg") inc = 10 n = 10 rpixel=[] # grabs bottom center of image, keeps image ratio. larger inc smaller imaged grabed def bottomcenter(inc,img): y,x,z = img.shape h = x/2 x1 = h - (x/inc) x2 = h + (x/inc) y1 = y - (y/inc) y2 = y bcsample = img[y1:y2, x1:x2] return(bcsample) # generates random selection of pixels def randompixel(img,n): y,x,z = img.shape in range (n): xrand = random.randrange(0,x) yrand = random.randrange(0,y) rpix = yrand,xrand rpixel.append(rpix) return(rpixel) roadsample = bottomcenter(inc,img) randompixel(roadsample,n) in rpixel: #px=b.g.r px = roadsample[i] b,g,r in px: ub = max(b) ug = max(g) ur = max(r) lb = min(b) lg = min(g) lr = min(r) boundary = [([lb,lg,lr],[ub,ug,ur])] print(boundary) #for (lower, upper) in boundary: # create numpy arrays boundaries # lower = np.array(lower, dtype = "uint8") # upper = np.array(upper, dtype = "uint8") # find colors within specified boundaries , apply # mask #mask = cv2.inrange(img, lower, upper) #output = cv2.bitwise_and(img, img, mask = mask) # save images #cv2.imwrite(name + "_roadarea.png", np.hstack([img, output]))
there problems code :
firstly, should change
randompixel(roadsample,n)
to
rpixel=randompixel(roadsample,n)
even though works because python nice , rpixel delcared beforehand, it's messy : randompixel function returning rpixel , forgetting it.
secondly,the error mention in comment comes double loop. first loop ok, loop every item in rpixel. following line
px = roadsample[i]
gets corresponding pixel in cropped image, ok. px 3 element array. iterate in need like
for color in px
not
for b,g,r in px
because here trying iterate on elements of px @ once. error telling you, "i can't iterate on b value of px, because it's number !" seems you're new programming, don't hesitate use lot of "print" or debug ide see variables @ given time
finally, question, if understood correctly, here proposed code :
import cv2 import numpy np def bottomcenter(inc,img): y,x,z = img.shape h = x/2 x1 = h - (x/inc) x2 = h + (x/inc) y1 = y - (y/inc) y2 = y bcsample = img[y1:y2, x1:x2] return(bcsample) #read image full_road = cv2.imread(fullroad_path) #crop road part of road there no line inc=10 cropped_road=bottomcenter(inc,road) #seperate image in each channel (yes, can that, numpy handy !) blue=cropped_road[:,:,0]; green=cropped_road[:,:,1]; red=cropped_road[:,:,2]; #computing mean , std of each channel blue_mean=np.mean(blue); green_mean=np.mean(green); red_mean=np.mean(red); blue_std=np.std(blue); green_std=np.std(green); red_std=np.std(red); #getting positions of pixels in [color +-std] mask = cv2.inrange(fullroad, np.array([blue_mean-blue_std,green_mean-green_std,red_mean-red_std]), np.array([blue_mean+blue_std,green_mean+green_std,red_mean+red_std])) #masking image output = cv2.bitwise_and(full_road, full_road, mask = mask)
Comments
Post a Comment