【问题标题】:Digitizing heatmap and map pixels to values数字化热图并将像素映射到值
【发布时间】:2020-07-01 19:15:33
【问题描述】:

我想将热图数字化,此来源中的面板 D

image

作为第一步,我尝试在opencv中读取图像并获得一个矩阵

import cv2
from pprint import pprint


def read_as_digital(image):
    # mage dimensions
    h = image.shape[0]
    w = image.shape[1]
    print(h, w)
    pass


if __name__ == '__main__':

    image = cv2.imread('ip.jpg', 1)
    pprint(image)

    read_as_digital(image)

我可以将图像读取为矩阵,但我不知道如何在热图中指定单元格的开头(对应于图像面板 D 中的不同子图)。最后,我想将像素映射到值。

任何关于如何进行的建议都会非常有帮助

编辑1:

我试图获取点击时的值

例如,当我考虑源中提供的热图的一小部分时

我希望获得图像中每个单元格(以黄点为中心)的平均值。 单击不同的点会产生不同的值。单击已匹配的单元格 在不同的点给出不同的 RGB 值。

任何关于如何获得每个单元格平均值的建议(例如)都会很有帮助。

EDIT2:

我已经尝试了更新的代码。

这个的平均平均值((例如))效果很好。但是,它旁边的单元格存在问题。当我单击相邻的单元格时,代码显示的平均值是 3 个具有相同颜色的单元格。如果有一种方法来限制单元格大小,那就太好了,就像指定一个边界,在代码中应该计算平均值。编辑 1 中呈现的图像有 6 行和 6 列。如果我们将其视为 6 x 6 矩阵,例如 A,则应为矩阵的每个 Aijth 条目获得平均值。

【问题讨论】:

  • 我需要一些细节: 1- 你想要像指定图像一样的热图吗?你有热图图像吗?它是连续的吗?你想让它被mozaiced吗? 2-或者你有指定的图像,你想从中提取热图值?!
  • @a-sam 非常感谢您的回复。我有指定的图像,我想从中提取热图值。
  • 请更好地指定您想要使用的确切输入图像。
  • 你可以做一些非常基本的图像识别来找到盒子的大小,然后简单地平均边缘和中心边缘内的所有内容。
  • 但目前最简单的方法是联系作者并索要数据。

标签: python-3.x image opencv image-processing heatmap


【解决方案1】:
import cv2
import numpy as np

# print pixel value on click
def mouse_callback(event, x, y, flags, params):
    if event == cv2.EVENT_LBUTTONDOWN:
        # get specified color
        row = y
        column = x
        color = image[row, column]
        print('color = ', color)
        # calculate range
        thr = 20  # ± color range
        up_thr = color + thr
        up_thr[up_thr < color] = 255
        down_thr = color - thr
        down_thr[down_thr > color] = 0
        # find points in range
        img_thr = cv2.inRange(image, down_thr, up_thr)  # accepted range
        height, width, _ = image.shape
        left_bound = x - (x % round(width/6))
        right_bound = left_bound + round(width/6)
        up_bound = y - (y % round(height/6))
        down_bound = up_bound + round(height/6)
        img_rect = np.zeros((height, width), np.uint8)  # bounded by rectangle
        cv2.rectangle(img_rect, (left_bound, up_bound), (right_bound, down_bound), (255,255,255), -1)
        img_thr = cv2.bitwise_and(img_thr, img_rect)
        # get points around specified point
        img_spec = np.zeros((height, width), np.uint8)  # specified mask
        last_img_spec = np.copy(img_spec)
        img_spec[row, column] = 255
        kernel = np.ones((3,3), np.uint8)  # dilation structuring element
        while cv2.bitwise_xor(img_spec, last_img_spec).any():
            last_img_spec = np.copy(img_spec)
            img_spec = cv2.dilate(img_spec, kernel)
            img_spec = cv2.bitwise_and(img_spec, img_thr)
            cv2.imshow('mask', img_spec)
            cv2.waitKey(10)
        avg = cv2.mean(image, img_spec)[:3]
        print('mean = ', np.around(np.array(avg), 2))
        global avg_table
        avg_table[:, 6 - int(x / (width/6)), 6 - int(y / (height/6))] = avg
        print(avg_table)

# average value of each cell in 6x6 matrix
avg_table = np.zeros((3, 6, 6))

# create window and callback
winname = 'img'
cv2.namedWindow(winname)
cv2.setMouseCallback(winname, mouse_callback)

# read & display image
image = cv2.imread('ip.jpg', 1)
image = image[3:62, 2:118]  # crop the image to 6x6 cells
cv2.imshow(winname, image)
cv2.waitKey()  # press any key to exit
cv2.destroyAllWindows()

请注意,OpenCV 具有 BGR 颜色格式而不是 RGB。因此,例如,单击红色将打印出[0, 0, 255]

您可以更改thr 以调整可接受颜色的范围。

图像被裁剪为仅包含 6 x 6 矩阵部分。

【讨论】:

  • @Natasha - 更新了我的答案。我在 HSV 颜色空间中尝试过阈值操作,但它没有给出令人满意的结果。反正这个也不错。
  • @Natasha - 再次更新。大小不是 6 的倍数,因此在某些点可能会丢失边界框。 the source image好像不能下载为png文件,但是可以放大。我建议您尝试使用更大屏幕截图的代码。
  • 您能否解释一下您如何决定在image[3:62, 2:118] 行中裁剪的单元格?更新后的代码按预期工作,但您能否建议如何自动化以下操作:现在,我试试单击 6 x 6 单元格中每个单元格的中心并获取每个单元格的平均值。我想自动化这个(或者这可以是用户的选择 - 是通过单击获得 6 x 6 单元格中单个单元格的平均值,还是简单地获得输出 6 x 6 矩阵/ nd 数组给出每个单元格的平均值)
  • @Natasha - 我从绘画中查看了边界像素位置 :) 如果您将使用 6x6 矩阵方法,则需要裁剪图像。如果要自动查找每个单元格的平均值,则需要找到每个单元格中的主色。选择某个点,按照答案进行区域生长,如果该区域大于单元格面积的一半,那么您可以使用该点。否则,从剩余区域中选择另一个点。
  • 我在您的代码中添加了一个编辑来调整输入图像的大小。感谢您的回复:)。我不太确定如何做到这一点,“选择一些点,按照答案进行区域生长,如果该区域大于单元格面积的一半,那么您可以使用点。否则,从剩余区域中选择另一个点”。因此,我将手动逐行单击序列中的每个单元格,并尝试将np.array(avg) 存储在矩阵/nd 数组中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-07-10
  • 2020-01-13
  • 1970-01-01
  • 1970-01-01
  • 2022-10-01
  • 1970-01-01
  • 2021-03-13
相关资源
最近更新 更多