如何在排除异常值的图像中找到像素颜色范围?

时间:2016-12-22 15:10:51

标签: python-2.7 opencv numpy pixel

我有这个代码随机生成图像尺寸中的10个像素位置。然后,我想获取每个像素位置并找到GBR值,然后找到最大的g值,b值,r值和最小的g值b值和r值。然后,我找到了一些可以采用这些颜色边界并创建蒙版图像的代码。我可能想要合并一个平均g,b,r值并计算每个的标准差,并使用它来消除异常值。

或者代替使用我编写的代码生成10个随机像素,如果有办法获得颜色范围+ - 1图像的平均颜色标准偏差?

请参阅以下代码:

    import cv2
import numpy as np
import random

name = "Highway"

img = cv2.imread(name + ".jpg")
inc = 10
n = 10
rpixel=[]

# grabs bottom center of image, keeps image ratio. the larger the inc is the smaller the 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 a random selection of pixels

def randompixel(img,n):

    y,x,z = img.shape

    for i 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)




for i in rpixel:

    #px=B.G.R   
    px = roadsample[i]

    for 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 from the boundaries
#   lower = np.array(lower, dtype = "uint8")
#   upper = np.array(upper, dtype = "uint8")

# find the colors within the specified boundaries and apply
# the mask
#mask = cv2.inRange(img, lower, upper)
#output = cv2.bitwise_and(img, img, mask = mask)

# save the images
#cv2.imwrite(name + "_roadarea.png", np.hstack([img, output]))

1 个答案:

答案 0 :(得分:0)

您的代码存在一些问题:

首先,你应该改变

randompixel(roadsample,n)

rpixel=randompixel(roadsample,n)

尽管它很有效,因为Python很好并且rpixel预先进行了渲染,但它很麻烦:你的randompixel函数正在返回rpixel而你却忘了它。

其次,您在评论中提到的错误来自您的double for循环。第一个for循环是OK,它将循环rpixel中的每个项目。以下一行

px = roadsample[i]

获取裁剪图像中的相应像素,确定。所以px是一个3元素数组。要迭代它,你需要做类似

的事情
for color in px

不是

for b,g,r in px

因为在这里你试图一次迭代px的所有元素。这就是你的错误告诉你的,"我不能迭代px的b值,因为它只是一个数字!" 看起来你对编程很陌生,不要犹豫使用很多" print"或调试IDE,以查看在任何给定时间您的变量是什么样的

最后,对于您的问题,如果我理解正确,这是一个建议的代码:

import cv2
import numpy as 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 to get a part of road where there is no line
inc=10
cropped_road=bottomcenter(inc,road)

#seperate image in each channel (yes, you can do that, numpy is handy !)
blue=cropped_road[:,:,0]; green=cropped_road[:,:,1]; red=cropped_road[:,:,2];

#computing mean and 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 the image
output = cv2.bitwise_and(full_road, full_road, mask = mask)