简体   繁体   English

如何在 Python 中生成图像区域的直方图? (用openCV确定轮廓后)

[英]How to generate histograms on zones of an image in Python? (after determining contours with openCV)

I have zero experience in Python but I need to use it as a data processing step for my project.我在 Python 方面的经验为零,但我需要将它用作我项目的数据处理步骤。 I'm working with drone thermal images of vineyards and the objective is to separate the canopy pixels from the ground pixels based on elevation and temperature.我正在处理葡萄园的无人机热图像,目的是根据海拔和温度将树冠像素与地面像素分开。 Using a DEM (digital elevation model), a first distinction was made between the canopy and the ground.使用 DEM(数字高程模型),首先区分了树冠和地面。 This results in a binary mask layer that can be put on top of the thermal image of the vineyard.这会产生一个二进制掩膜层,可以放在葡萄园的热图像之上。 That way, I now have a thermal image in Python of which most of the ground pixels are 0 and the canopy pixels have a value between 0 and 65535 representing the temperature.这样,我现在在 Python 中有一个热图像,其中大部分地面像素为 0,而树冠像素的值介于 0 和 65535 之间,表示温度。 However, since the first distinction (using the DEM) is not precise enough, some ground pixels are also included in the canopy mask.然而,由于第一个区分(使用 DEM)不够精确,一些地面像素也包含在冠层掩膜中。

Now I want to make a second distinction using the temperature of the selected zones.现在我想使用所选区域的温度进行第二次区分。 I was able to make contours of all the canopy zones with opencv (so I have a complete list of all the contours representing the canopy zones - with some ground pixels).我能够使用 opencv 制作所有树冠区域的轮廓(所以我有代表树冠区域的所有轮廓的完整列表 - 带有一些地面像素)。 I aim to make a histogram per contour zone displaying the density of each pixelvalue within that zone.我的目标是制作每个轮廓区域的直方图,显示该区域内每个像素值的密度。 Hopefully I can then delete the pixels that are too hot (ie groundpixels).希望我可以删除太热的像素(即groundpixels)。

Does anyone know how to generate histograms for every (filled) contour of an image?有谁知道如何为图像的每个(填充)轮廓生成直方图? The format now is an 6082x4922 ndarray with values between 0 and 65535 of datatype uint16.现在的格式是 6082x4922 ndarray,其值介于 0 和 65535 之间,数据类型为 uint16。 I use PyCharm as an IDE.我使用 PyCharm 作为 IDE。

Thanks in advance!提前致谢!

Approach:方法:

  • Iterate through each contour in the mask遍历掩码中的每个轮廓
  • Find locations of pixels present in the mask查找掩码中存在的像素位置
  • Find their corresponding values in the given image在给定的图像中找到它们对应的值
  • Compute and plot the histogram计算并绘制直方图

Code:代码:

# reading given image in grayscale
img = cv2.imread('apples.jpg', 0)

在此处输入图像描述

# reading the mask in grayscale
img_mask = cv2.imread(r'apples_mask.jpg', 0)
# binarizing the mask
mask = cv2.threshold(img_mask,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)[1]

在此处输入图像描述

# find contours on the mask
contours, hierarchy = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

# the approach is encoded within this loop
for i, c in enumerate(contours):
    # create a blank image of same shape
    black = np.full(shape = im.shape, fill_value = 0, dtype = np.uint8)
    # draw a single contour as a mask
    single_object_mask = cv2.drawContours(black,[c],0,255, -1)
    # coordinates containing white pixels of mask
    coords = np.where(single_object_mask == 255)
    # pixel intensities present within the image at these locations
    pixels = img[coords]
    # plot histogram
    plt.hist(pixels,256,[0,256])
    plt.savefig('apples_histogram_{}.jpg'.format(i)')
    # to avoid plotting in the same plot
    plt.clf()

Result: (the following are the 3 histogram plots)结果:(以下是3个直方图)

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

If you remove plt.clf() , all the histograms will be plotted on a single plot如果删除plt.clf() ,所有直方图都将绘制在一个图上

You can extend the same approach for your use case您可以为您的用例扩展相同的方法

Original image:原图:

在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM