【问题标题】:How to draw a point in an image using given coordinate如何使用给定的坐标在图像中绘制一个点
【发布时间】:2019-08-27 22:45:48
【问题描述】:

我加载了图像并尝试在图像中绘制一个红点

img=mpimg.imread('./images/im00001.jpg')
red = [0,0,255]
# Change one pixel
img[ 0.,-26.10911452,0. ]=red
imgplot = plt.imshow(img)

但出现以下错误

ValueError:赋值目标是只读的

【问题讨论】:

  • 我想img 是 3 维的,因此您将列表设置为 3 维数组中的值 (img[ 0.,-26.10911452,0. ])。虽然我不明白为什么会导致你的错误。也可能不相关,你为什么使用浮点数来索引你的数组?

标签: python image numpy matplotlib imread


【解决方案1】:

你所做的实际上改变了你的形象。

要在显示的图像上绘制点,您可以在matplotlib 图形中显示图像,然后在其上绘制点。您可以使用pyplot.plot() 函数绘制点,或使用pyplot.scatter() 函数绘制点数组。

image = mpimg.imread("road.jpg")
pts = np.array([[330,620],[950,620],[692,450],[587,450]])

plt.imshow(image)
plt.plot(640, 570, "og", markersize=10)  # og:shorthand for green circle
plt.scatter(pts[:, 0], pts[:, 1], marker="x", color="red", s=200)
plt.show()

【讨论】:

    【解决方案2】:

    你在正确的轨道上。您可以使用 Numpy 拼接更改像素的属性

    img[x,y] = [B,G,R]
    

    例如,要将(50,50) 处的像素更改为红色,您可以这样做

    img[50,50] = [0,0,255]
    

    在这里我们将单个像素更改为红色(它非常小)

    import cv2
    import numpy as np
    
    width = 100
    height = 100
    
    # Make empty black image of size (100,100)
    img = np.zeros((height, width, 3), np.uint8)
    
    red = [0,0,255]
    
    # Change pixel (50,50) to red
    img[50,50] = red
    
    cv2.imshow('img', img)
    cv2.waitKey(0)
    

    另一种方法是使用cv2.circle() 在原地绘制您的点。

    函数头是

    cv2.circle(image, (x, y), radius, (B,G,R), thickness)
    

    使用这个,我们得到相同的结果

    cv2.circle(img, (50,50), 1, red, -1)
    

    【讨论】:

    • 你能给我看一下先读图片的例子吗?就像我做的那样 img = imread("file").
    • 对不起,我忘了说这个方法使用了 OpenCV 库。您可以使用pip install opencv-python 安装它。如果您决定使用matplotlib,请参考@arsho 以获得他的最佳答案
    【解决方案3】:

    mpimg 表示您正在使用matplotlib 读取图像。

    使用matplotlib 处理图像时要记住以下几点:

    • matplotlib 将图像数据存储到 Numpy 数组中。所以,type(img) 将返回 <class 'numpy.ndarray'>。 (参考 1)
    • ndarray 的形状代表图像的高度、宽度和波段数。
    • 每个内部列表代表一个像素。对于 RGB 图像内部列表长度为 3。对于 RGBA 图像内部列表长度为 4。列表的每个值存储 0.0 到 1.0 之间的浮点数据。每个值代表像素的 R(红色)、G(绿色)、B(蓝色)和 A(Alpha / 透明度)的值。
    • 对于 RGB 图像,要将像素设置为红色,应分配像素:[1, 0, 0]
    • 对于 RGBA 图像,要将像素设置为红色,应分配像素:[1, 0, 0, 1]
    • matplotlib 中,图形的大小是固定的,内容会被拉伸/压缩/插值以适合图形。因此,保存图像后,分辨率可能会发生变化。 (参考 2)

    根据这些要点,我通过在其中心放置一个红点来编辑 RGBA 图像(png 格式)。

    原图:

    编辑后的图片:

    code.py:

    import numpy as np
    import matplotlib.pyplot as plt
    import matplotlib.image as mpimg
    
    # dpi for the saved figure: https://stackoverflow.com/a/34769840/3129414
    dpi = 80
    
    # Set red pixel value for RGB image
    red = [1, 0, 0]
    img = mpimg.imread("minion.png")
    height, width, bands = img.shape
    
    # Update red pixel value for RGBA image
    if bands == 4:
        red = [1, 0, 0, 1]
    
    # Update figure size based on image size
    figsize = width / float(dpi), height / float(dpi)
    
    # Create a figure of the right size with one axes that takes up the full figure
    figure = plt.figure(figsize=figsize)
    axes = figure.add_axes([0, 0, 1, 1])
    
    # Hide spines, ticks, etc.
    axes.axis('off')
    
    # Draw a red dot at pixel (62,62) to (66, 66)
    for i in range(62, 67):
        for j in range(62, 67):
            img[i][j] = red
    
    # Draw the image
    axes.imshow(img, interpolation='nearest')
    
    figure.savefig("test.png", dpi=dpi, transparent=True)
    

    参考资料:

    1. Matplotlib official tutorial
    2. Stackoverflow answer on saving image in same resolution as original image

    【讨论】:

    • ValueError Traceback (最近一次调用最后一次) in 2 for i in range(62, 67): 3 for j in range(62, 67) : ----> 4 img[i][j] = red ValueError: assignment destination is read-only
    猜你喜欢
    • 2018-09-22
    • 1970-01-01
    • 2013-10-14
    • 1970-01-01
    • 2017-05-20
    • 2019-06-02
    • 2020-07-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多