寻找每种颜色中每列的平均BGR值

时间:2017-06-07 22:42:01

标签: python numpy graph colors average

我们正在开发一个查看96孔板的代码。我们有每口井的中心坐标。然后我们创建了一个for循环,它允许我们获得每个井的BGR值。但是,我们需要以某种方式组织每个列并平均这些值。我相信我们从第一个循环中得到一个错误。有了这个,看起来这个函数只能通过第一个循环而不是第二个循环。当我运行它时,我得到3个值(假设是bgr值),然后继续推出平均值。它似乎也重复了一些平均值。对我可以更改的内容或初看错误的任何建议。我将在下面提供图片和图例。

图片链接是: http://imgur.com/Eb87ZxW(图片已缩放,因此坐标可能无法与上传的图片一起使用) http://imgur.com/P4tPPXX

import cv2, numpy as np, sys

#filename will be taken from the command line and process as the image variable
#filename= sys.argv([1])
img = cv2.imread('greenandblueplate.jpg')

#centroids
wells = [img[110,97], img[184,97], img[254,97], img[324,97], img[396,96], img[466,97], #columnH 12-7
         img[537,96], img[607,97], img[680,96], img[750,97], img[820,96], img[891,97], #columnH 6-1
         img[110,165],img[184,165],img[254,165],img[324,165],img[396,165],img[466,165], #columnG 12-7
         img[537,165],img[607,165],img[680,165],img[750,166],img[820,165],img[891,165], #columnG 6-1
         img[110,235],img[184,235],img[254,235],img[324,235],img[396,235],img[466,235], #columnF 12-7
         img[537,235],img[607,235],img[680,235],img[750,235],img[820,235],img[891,235], #columnF 6-1
         img[110,305],img[184,305],img[254,305],img[324,305],img[396,305],img[466,305], #columnE 12-7
         img[537,305],img[607,305],img[680,305],img[750,305],img[820,305],img[891,305], #columnE 6-1
         img[110,373],img[184,373],img[254,373],img[324,373],img[396,373],img[466,373], #columnD 12-7
         img[537,373],img[607,373],img[680,373],img[750,372],img[820,373],img[891,373], #columnD 6-1
         img[110,442],img[184,442],img[254,442],img[324,442],img[396,442],img[466,442], #columnC 12-7
         img[537,442],img[607,442],img[680,442],img[750,443],img[820,442],img[891,442], #columnC 6-1
         img[109,511],img[184,511],img[254,511],img[324,511],img[396,511],img[466,511], #columnB 12-7
         img[537,512],img[607,512],img[680,511],img[750,511],img[820,511],img[891,511], #columnB 6-1
         img[109,582],img[184,582],img[254,582],img[324,581],img[396,582],img[466,582], #columnA 12-7
         img[537,581],img[607,582],img[680,582],img[750,581],img[820,582],img[891,582]] #columnA 6-1

bAvgFilledWells = []
gAvgFilledWells = []
rAvgFilledWells = []

#filtering out the centroids that are not needed
#and getting the bgr values for the first color on the plate
for center in wells:
    if center[1] > 124:
        if center[0] < 360:
            b = img[center[0]-4: center[0]+5, center[1]-4: center[1]+5, 0]
            g = img[center[0]-4: center[0]+5, center[1]-4: center[1]+5, 1]
            r = img[center[0]-4: center[0]+5, center[1]-4: center[1]+5, 2]
            bAvg = np.mean(b)
            gAvg = np.mean(g)
            rAvg = np.mean(r)

            bAvgFilledWells.append(bAvg)
            gAvgFilledWells.append(gAvg)
            rAvgFilledWells.append(rAvg)
            print(center)
            print("For the first color, average value for blue is:", bAvg)
            print("For the first color, average value for green is:", gAvg)
            print("For the first color, average value for red is:", rAvg)


bAvgFilledWells2 = []
gAvgFilledWells2 = []
rAvgFilledWells2 = []

#filtering out the centroids that are not needed
#and getting the bgr values for the second color on the plate        
for center in wells:
    if center[1] > 124:
        if center[0] > 360 and center[0] < 642:
            b2 = img[center[0]-4: center[0]+5, center[1]-4: center[1]+5, 0]
            g2 = img[center[0]-4: center[0]+5, center[1]-4: center[1]+5, 1]
            r2 = img[center[0]-4: center[0]+5, center[1]-4: center[1]+5, 2]
            bAvg2 = np.mean(b2)
            gAvg2 = np.mean(g2)
            rAvg2 = np.mean(r2)

            print(center)
            print("For the second color, average value for blue is:", bAvg2)
            print("For the second color, average value for green is:", gAvg2)
            print("For the second color, average value for blue is:", rAvg2)
            bAvgFilledWells2.append(bAvg2)
            gAvgFilledWells2.append(gAvg2)
            rAvgFilledWells2.append(rAvg2)

2 个答案:

答案 0 :(得分:1)

一开始庞大的数组wells看起来很麻烦且重复。可以通过创建列A-H和行1-12的X / Y位置列表来改进它。

这是你的错误的来源:在循环中,你正在解析center,好像它是x,y位置,但实际上它是从img检索的像素。

取而代之的是:

columns = [110,124,160] # give 8 values for columns A-H
rows = [97, 165, 235] # give 12 values for rows 1-12
#...
for row = 0 to 3:
    for column = 0 to 7:
        center_column = columns[column]
        center_row = rows[row]
        #... get img pixels and process b,g,r values

答案 1 :(得分:1)

以下是重写代码的方法:

import cv2
from itertools import product
import numpy as np
import sys

# image coordinates
ROWS = (891, 820, 750, 680, 607, 537, 466, 396, 324, 254, 184, 110)   # rows 1..12
COLS = (582, 511, 442, 373, 305, 235, 165, 97)                        # cols A..H

def get_rect_avg_color(img, x, y, w=8, h=8):
    """
    Return the BGR average color of a rectangular area of the image
      centered on (x,y) with width w and height h
    """
    half_w = w // 2
    half_h = h // 2
    # extract the rectangular area
    rect = img[x - half_w: x + (w - half_w) + 1, y - half_h: y + (h - half_h) + 1]
    # average each channel independantly
    avg_col = rect.mean(axis=(0,1))
    return avg_col    # returns [avg_b, avg_g, avg_r]

def get_cells_avg_color(img, cells):
    """
    Return the BGR average color of a list of cells
    """
    cell_colors = np.vstack(get_rect_avg_color(img, *cell) for cell in cells)
    return cell_colors.mean(axis=0)    # returns [avg_b, avg_g, avg_r]

def get_cells(col_from, col_to, row_from, row_to):
    """
    Return a list of all cells in a rectangular block

    col_from, col_to  in "A".."H"
    row_from, row_to  in 1..12

    col_to and row_to are inclusive
    """
    col_from  = ord(col_from.upper()) - ord("A")
    col_to    = ord(col_to  .upper()) - ord("A")
    col_from, col_to = min(col_from, col_to), max(col_from, col_to)
    row_from -= 1
    row_to   -= 1
    row_from, row_to = min(row_from, row_to), max(row_from, row_to)
    return product(ROWS[row_from:row_to + 1], COLS[col_from:col_to + 1])

def main(img_fname):
    img = cv2.imread(img_fname)

    first_cells = get_cells("A", "G", 9, 12)
    first_avg = get_cells_avg_color(img, first_cells)
    print("First color average: blue {:0.2f}, green {:0.2f}, red {:0.2f}".format(*first_avg))

    second_cells = get_cells("A", "G", 5, 8)
    second_avg = get_cells_avg_color(img, second_cells)
    print("Second color average: blue {:0.2f}, green {:0.2f}, red {:0.2f}".format(*second_avg))

if __name__ == "__main__":
    if len(sys.argv) == 2:
        main(sys.argv[1])
    else:
        print("Usage: python {} plate.jpg".format(__name__))