【问题标题】:Blurring specific points of an image and storing the pixel value模糊图像的特定点并存储像素值
【发布时间】:2020-11-05 09:42:37
【问题描述】:

我有大量图像,我想检查不同位置的像素强度并存储 50 张图像的值。我有一个 9 像素的网格,代表图像的不同 22 个特定坐标处的 1 个点。我想要做的是在每 22 个位置计算 9 个像素的网格内的平均值,这将是该特定黑点的平均值。例如:

每个黑点都是一个 9 像素的网格,我想计算它们的平均值并按顺序存储它们。在实践中,我有以下列表,它们是所有 22 个坐标的每个网格中像素的实际坐标:

    grid_coords = [
[60, 25], 
[61, 25], 
[59, 25], 
[60, 24], 
[59, 24], 
[61, 24], 
[60, 26], 
[61, 26], 
[59, 26], 
[110, 25], 
[111, 25], 
[109, 25], 
[110, 24], 
[109, 24], 
[111, 24], 
[110, 26], 
[111, 26], 
[109, 26], 
[175, 25], 
[176, 25], 
[174, 25], 
[175, 26],
[174, 26], 
[176, 26], 
[175, 24], 
[174, 24], 
[176, 24], 
[65, 40], 
[66, 40], 
[64, 40], 
[65, 39], 
[66, 39], 
[64, 39], 
[65, 41], 
[66, 41], 
[64, 41], 
[110, 50], 
[111, 50], 
[109, 50], 
[110, 49], 
[109, 49], 
[111, 49], 
[110, 51], 
[109, 51], 
[111, 51], 
[170, 40], 
[171, 40], 
[169, 40], 
[170, 39], 
[171, 39], 
[169, 39], 
[170, 41], 
[171, 41], 
[169, 41], 
[43, 55], 
[44, 55], 
[45, 55], 
[43, 56], 
[44, 56], 
[45, 56], 
[43, 54], 
[44, 54], 
[45, 54], 
[180, 55], 
[181, 55], 
[179, 55], 
[180, 56], 
[181, 56], 
[179, 56], 
[181, 54], 
[180, 54], 
[179, 54], 
[30, 85], 
[31, 85], 
[29, 85], 
[30, 86], 
[31, 86], 
[29, 86], 
[30, 84], 
[31, 84], 
[29, 84], 
[65, 75], 
[66, 75], 
[64, 75], 
[65, 74], 
[66, 74], 
[64, 74], 
[65, 76], 
[66, 76], 
[64, 76], 
[100, 105], 
[101, 105], 
[99, 105], 
[100, 104], 
[101, 104], 
[99, 104], 
[100, 106], 
[99, 106], 
[101, 106], 
[125, 105], 
[126, 105], 
[124, 105], 
[125, 104], 
[126, 104], 
[124, 104], 
[125, 106], 
[124, 106], 
[126, 106], 
[160, 75], 
[161, 75], 
[159, 75], 
[160, 74], 
[161, 74], 
[159, 74], 
[160, 76], 
[161, 76], 
[159, 76], 
[190, 85], 
[191, 85], 
[189, 85], 
[190, 86], 
[191, 86], 
[189, 86], 
[190, 84], 
[191, 84], 
[189, 84], 
[30, 142], 
[31, 142], 
[29, 142], 
[30, 143], 
[31, 143], 
[29, 143], 
[30, 141], 
[31, 141],
[29, 141], 
[75, 142], 
[76, 142], 
[74, 142], 
[75, 143], 
[76, 143], 
[74, 143], 
[75, 141], 
[76, 141], 
[74, 141], 
[145, 142], 
[146, 142], 
[144, 142], 
[145, 143], 
[146, 143], 
[144, 143], 
[145, 141], 
[146, 141], 
[144, 141], 
[180, 142], 
[181, 142], 
[179, 142], 
[180, 143], 
[181, 143], 
[179, 143], 
[180, 141], 
[181, 141], 
[179, 141], 
[85, 176], 
[84, 176], 
[86, 176], 
[85, 177], 
[84, 177], 
[86, 177], 
[85, 175], 
[84, 175], 
[86, 175], 
[125, 176], 
[126, 176], 
[124, 176], 
[125, 177], 
[126, 177], 
[124, 177], 
[125, 175], 
[126, 175], 
[124, 175], 
[70, 190], 
[71, 190], 
[69, 190], 
[70, 189], 
[71, 189], 
[69, 189], 
[70, 191], 
[71, 191], 
[69, 191], 
[153, 190], 
[154, 190], 
[152, 190], 
[153, 189], 
[154, 189], 
[152, 189], 
[154, 191], 
[153, 191], 
[152, 191]]

我目前正在做的是: 对于我拥有的文件夹中的每个图像,对于给定的坐标,我一次只获取 1 个像素的强度值,该坐标代表 22 个位置,而不计算它们的平均值,如下所示:

def loadImages(path):

    imagesList = listdir(path)
    loadedImages = []
    for image in imagesList:
        img = PImage.open(path + image)
        arr = np.array(img)
        loadedImages.append(arr)


    return loadedImages 


img_folder = loadImages(path)
for img in img_folder:
    img_feats = []
    for coords in coords_array:
        img_feats.append(img[coords[0], coords[1]])
    face_image_vector.append(img_feats) 

这为给定的 x 和 y 坐标数组提取单个像素,这几乎是我想要做的。

因此,我想要实现的是: 对于上面给定数组的每 22 个坐标/位置,计算由 3x3 像素组成的每个点的平均像素,并将它们存储在向量中。因此,如果我有 10 张图片,我将有一个 10x22 的特征向量,如果我有 50 张图片,我应该有一个 50x22 的特征向量。

目前我可以使用我的代码来存储每 22 个单个像素的值,而无需计算它们的相邻像素,这是我想做的。

【问题讨论】:

  • 总而言之,您想要每个黑色像素的平均值吗?其中有 22 个,所以你想要每张图像有 22 个 (x, y) 坐标?您是否尝试提取面部关键点特征?
  • 是的,确切地说,从每个黑色像素网格中提取 22 个平均值以提取面部关键点特征,但专门针对文件夹内任何数量图像的坐标列表,这正是我的代码所做的,但它不计算黑色像素网格的平均值。
  • 你的grid_coords不应该有198个坐标吗? 22 个特征的 9 个坐标。你的有 201 个?
  • 是的,我修好了。我正在详尽地手写他们的位置,并没有注意到它有 3 个额外的坐标。
  • 我可以建议一个可能会更好的替代解决方案,但我需要确认这一点 - 您的目标基本上是获取黑点中心的坐标,对吗?

标签: python python-3.x numpy matplotlib image-processing


【解决方案1】:

使用您当前的方法,您需要做的是将坐标列表转换为 numpy 数组,以便 numpy 数组的每个元素对应于 (9, 2) 坐标网格。


grid_np = np.array(grid_coords) #grid_coords is the list of grids you gave
grid_np = grid_np.reshape(22,9,2) #total points, pixels per point, # of coords
grid_means = np.zeros((9,2)) #initialize empty array to store means

def centroid(pixel_grid):
    length = pixel_grid.shape[0]
    sum_x = np.sum(pixel_grid[:,0])
    sum_y = np.sum(pixel_grid[:,1])
    return np.array([sum_x / length, sum_y / length])

for i in range(0,len(grid_means)):
    # import pdb; pdb.set_trace()
    grid_means[i] = centroid(grid_np[i])

这会给你

grid_means = 
array([[ 60.,  25.],
       [110.,  25.],
       [175.,  25.],
       [ 65.,  40.],
       [110.,  50.],
       [170.,  40.],
       [ 44.,  55.],
       [180.,  55.],
       [ 30.,  85.]])

############################################## ###################################

但是,如果我要解决这个问题,我会使用 OpenCV 来解决。我们可以通过阈值和斑点检测的结合来获得关键点的坐标。

# Mask off the black points to 'red', or any unique colour which will help in thresholding.
im = cv2.imread("CDsjQ.png")
orig_im = im.copy()
indices = np.where(im==0)
im[indices[0], indices[1], :] = [0, 0, 255] #OpenCV follows (B,G,R) color indexing
img_hsv = cv2.cvtColor(im, cv2.COLOR_BGR2HSV) #Change to HSV Color channel

现在我们要对图像进行阈值处理,以便隔离图像中的这些red 点。

https://stackoverflow.com/questions/45677452/using-masks-to-apply-different-thresholds-to-different-parts-of-an-image
# this function only masks off red, if you choose another colour you have to create a mask again.
def isolate_red(main_img, sens):
    lower_red = np.array([0, 50, 50])
    upper_red = np.array([10, 255, 255])
    mask1 = cv2.inRange(main_img, lower_red, upper_red)
    lower_red = np.array([170, 50, 50])
    upper_red = np.array([180, 255, 255])
    mask2 = cv2.inRange(main_img, lower_red, upper_red)
    mask = mask1 + mask2
    output_img = main_img.copy()
    output_img[np.where(mask == 0)] = 0
    thresh = cv2.bitwise_not(output_img)
    return thresh

thresh = isolate_red(img_hsv, 20)

现在,在阈值化之后,我们可以使用斑点检测器来查找“斑点”。

im = cv2.blur(thresh, (5,5)) #blur to remove noise

params = cv2.SimpleBlobDetector_Params()
params.minThreshold = 100
params.maxThreshold = 400

detector = cv2.SimpleBlobDetector_create(params)
keypoints = detector.detect(im) #keypoints is an object
for key in keypoints:
    print(key.pt[0], key.pt[1]) #access the coordinates from each obj
im_with_keypoints = cv2.drawKeypoints(orig_im, keypoints, np.array([]), (0,0,255), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
cv2.imwrite("Keypoints.png", im_with_keypoints)
Positions in pixel values :
682.5365600585938 473.8377380371094
700.7807006835938 501.54119873046875
558.1123657226562 383.11236572265625
703.1123657226562 371.11236572265625
568.6876831054688 354.10595703125
693.1123657226562 347.11236572265625
615.1123657226562 296.11236572265625
647.1123657226562 295.11236572265625
706.1123657226562 293.11236572265625
541.1123657226562 293.11236572265625
729.1123657226562 223.11236572265625
523.1123657226562 214.11236572265625
576.1123657226562 208.11236572265625
679.6876831054688 200.10594177246094
542.1123657226562 179.11236572265625
626.1123657226562 178.11236572265625
685.1123657226562 177.11236572265625
623.1123657226562 138.11236572265625
551.1123657226562 136.11236572265625
678.1123657226562 131.11236572265625
585.875 481.3636169433594

是的,有一些噪音点,但如果你稍微调整一下参数,你应该能够摆脱它们。或者,如果您可以定义要查找点的区域,则可以进行异常值删除。

【讨论】:

  • img_hsv 到底是什么?
  • img_hsv 正在将 RGB 色标图像转换为 hsv 色标。
  • 阈值化需要hsv
  • 是的,我想弄清楚为什么我没有定义 img_hsv
  • 当我做 thresh = isolate_red(img_hsv, 20) 时,我得到 NameError: name 'img_hsv' is not defined
【解决方案2】:

numpy 数组支持像img[[x1,x2,x3], [y1,y2,y3]] 这样的索引来获取元素的子集,然后你可以使用np.mean。我建议使用一个函数在给定的周围生成这 9 个点,然后只存储中心,它将减少硬编码值。

centers = [(30, 85), (30, 142), (44, 55), (60, 25), (65, 40), (65, 75), 
           (70, 190), (75, 142), (85, 176), (100, 105), (110, 25), (110, 50), 
           (125, 105), (125, 176), (145, 142), (153, 190), (160, 75), (170, 40), 
           (175, 25), (180, 55), (180, 142), (190, 85)]

def around(x, y):
    "returns x and y arrays of 3x3 grid around given coordinate."
    xs = []
    ys = []
    for dx in (-1, 0, 1):
        for dy in (-1, 0, 1):
            xs.append(x+dx)
            ys.append(y+dy)
    return (xs,ys)

for img in loadImages(path):
    img_feats = []
    for (x,y) in centers:
        img_feats.append(np.mean(img[around(x,y)]))
    face_image_vector.append(img_feats) 

【讨论】:

  • 这个方法计算一个像素周围的网格对吧?这是一个很好的解决方案。但是为什么每次我尝试为 50 张图像打印不同的值? (2662,), (2712,), (2762,), (2812,)。如果输出是 50 个图像的 50x22 维特征向量或 100 个图像的 100x22 维特征向量,那将是一个完美的解决方案
  • 我觉得应该,np.mean 不输出标量吗? face_image_vector 最终成为一个列表,其中元素的数量等于图像的数量,每个元素都是一个 22 个元素长的列表,所以它会输出一个 50x22 数组不是吗?
  • 数组正在堆叠,我尝试使用不同的向量,效果很好!
猜你喜欢
  • 2019-02-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多