对象检测如何将坐标内的操纵像素重新应用于原始图像以突出显示RoI

2024-04-27 14:47:37 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一组RGB图像的坐标(1920 x 1080)存储为一个列表,它是RoI(感兴趣区域),如下所示

[[1538, 234, 1626, 313],
[421, 231, 472, 288],
[918, 199, 988, 270],
[802, 0, 963, 114],
[1732, 0, 1909, 108]]

然后,我应用以下条件更改上面列表中坐标范围内的特定像素值,仅通过将像素更改为白色和黑色来突出显示这些ROI

for coords in list_of_coords:

            roi = orig[coords[1]:coords[3], coords[0]:coords[2]]

            roi [(roi > 200)] = 0
            roi [(roi < 200)] = 255

我现在如何获取这些新修改的像素值,并以一定的透明度将它们应用到原始图像的顶部?理想情况下,图像的其余部分将是相同的,而这些坐标内的值将在其顶部有一个透明遮罩

下面是所需输出的示例。我从Mask RCNN中获取了这一点,在矩形坐标中,添加了一点蓝色阴影以突出RoI。矩形框用上面的列表表示,蓝色阴影是根据上述条件进行的操作

enter image description here


Tags: 图像区域列表rgb像素coords条件感兴趣
2条回答

如果我完全理解的话,我仍然不确定你想要实现什么,但我试图回答你的问题:

基本上,对于每一组坐标,您需要执行以下操作:

  1. 获取原始图像的ROI剪切图。(你已经有了。)
  2. 生成一些二进制掩码(关于某些度量或任何您拥有的信息),以指示您要操作的ROI内部的哪个部分,例如图像中显示的汽车。在我下面的代码中,我选择用一些高蓝色通道值屏蔽任何像素
  3. 生成具有相同ROI大小的混合图像,并使用与生成的遮罩相关的纯色填充所有像素。在下面的代码中,我选择设置一些实心绿色
  4. 使用OpenCV的^{}方法进行alpha混合
  5. 将更新的ROI剪切图复制回原始图像

下面是我的示例图像和坐标的最终输出:

Final output

这是我的密码:

import cv2
from matplotlib import pyplot as plt
import numpy as np

# Load image
orig = cv2.imread('path/to/your/image.png')
orig_back = orig.copy()

# Set up list of list of coordinates (i.e. rectangular ROIs)
list_of_coords = [[90, 0, 260, 30],
                  [60, 180, 100, 250],
                  [300, 300, 380, 370]]

# Set up alpha for alpha blending
alpha = 0.5

for coords in list_of_coords:

    # Get ROI cutout of image
    roi = orig_back[coords[1]:coords[3], coords[0]:coords[2]]
    roi_back = roi.copy()

    # Generate some mask; examplary here: Mask anything with some high
    # blue channel value
    mask = roi[:, :, 0] > 172

    # Generate blend image; exemplary here: Blend with solid green
    blend = np.zeros_like(roi)
    blend[mask, 1] = 255

    # Alpha blending original image with blend image
    roi[mask, :] = cv2.addWeighted(roi[mask, :], alpha,
                                   blend[mask, :], 1 - alpha,
                                   0)

    # Copy updated ROI cutout back to image
    orig[coords[1]:coords[3], coords[0]:coords[2]] = roi

    # Add rectangle to image for location
    orig = cv2.rectangle(orig,
                         (coords[0], coords[1]),
                         (coords[2], coords[3]),
                         (0, 255, 0),
                         2)

    # Some visualization output for better understanding
    plt.figure(0, figsize=(16, 8))
    plt.subplot(221)
    plt.imshow(cv2.cvtColor(roi_back, cv2.COLOR_BGR2RGB))
    plt.title('ROI cutout of image')
    plt.subplot(222)
    plt.imshow(mask, cmap='gray')
    plt.title('Masked portion of ROI with high blue channel value')
    plt.subplot(223)
    plt.imshow(cv2.cvtColor(blend, cv2.COLOR_BGR2RGB))
    plt.title('Blend image, solid green')
    plt.subplot(224)
    plt.imshow(cv2.cvtColor(roi, cv2.COLOR_BGR2RGB))
    plt.title('Updated ROI cutout of image')
    plt.tight_layout()
    plt.show()


# Final output
cv2.imshow('Original image with updates and rectangles', orig)
cv2.waitKey(0)
cv2.destroyAllWindows()

下面是第一个ROI的额外可视化:

Additional visualization

希望这就是你想要的

                    
System information
                    
Platform:    Windows-10-10.0.16299-SP0
Python:      3.8.5
Matplotlib:  3.3.1
NumPy:       1.19.1
OpenCV:      4.4.0
                    

我想你正在寻找的答案是alpha blending。 如果您有描述中给出的两个图像(大小相同)(我们称它们为imgannotation),您可以执行以下操作:

alpha = 0.5 
# How much you want img to be opaque, alpha = 1 leads to your result being img,
# alpha = 0 to result==annotation
# with alpha = 0.5, you will get a blending with each image have the same 
# importance
result = cv2.addWeighted(img, alpha, annotation, 1-alpha, 0)

您可以找到有关函数here的一些解释

现在,如果您的图像大小不同,则需要在混合它们之前调整它们的大小(我会调整较小图像的大小,以获得与较大图像相同的大小),因此它应该如下所示:

width = img.shape[1]
height = img.shape[0]
dim = (width, height)
annotation = cv2.resize(annotation, dim) 

相关问题 更多 >