繁体   English   中英

OpenCV:着色失败

[英]OpenCV: Colorization failure

我正在读取图像,并且希望将所有非零像素的颜色都变为红色。 此外,背景由黑色组成。 我编写的尝试执行的代码如下所示:

import numpy as np
import cv2

second=cv2.imread('second.png') # read the picture

for i in range(second.shape[0]):
   for j in range(second.shape[1]):
       if second[i,j,0]!=0 and second[i,j,1]!=0 and second[i,j,2]!=0:# if it is not black pixel
           second[i,j,0]=0
           second[i,j,1]=0
           second[i,j,2]=255 # color it in red
cv2.imwrite('result.png',second) # save the colored picture

这是图片second.png

在此处输入图片说明

这是彩色图像result.png

在此处输入图片说明

为何有些像素没有被着色为红色? 需要注意的是,当我打印在这些位置的颜色像素值second.png对于未在红result.png ,我看他们是不是黑色的。

有谁知道为什么会这样吗?

您应使用or在您的条件下使用,以替换所有非黑色的像素:

import numpy as np
import cv2

second=cv2.imread('second.png') # read the picture

for i in range(second.shape[0]):
   for j in range(second.shape[1]):
       if second[i,j,0]!=0 or second[i,j,1]!=0 or second[i,j,2]!=0:# if it is not black pixel
           second[i,j,0]=0
           second[i,j,1]=0
           second[i,j,2]=255 # color it in red
cv2.imwrite('result.png',second) # save the colored picture

或者,您可以写if not(second[i,j,0]==0 and second[i,j,1]==0 and second[i,j,2]==0):作为条件,是等效的。

如果您不想只留下读通道,则可以使用cv::splitcv::merge 这是C ++示例:

#include <opencv2/opencv.hpp>


int main(int argc, char *argv[])
{
    cv::Mat src = cv::imread("second.png");
    cv::Mat b_g_r[3];
    cv::split(src, b_g_r);
    b_g_r[0] = cv::Mat::zeros(src.rows, src.cols, CV_8UC1); //blue to zeros
    b_g_r[1] = cv::Mat::zeros(src.rows, src.cols, CV_8UC1); //green to zeros
    cv::merge(b_g_r, 3, src);
    cv::imshow("Red", src);
    cv::waitKey();
    return 0;
}

结果:

David Zwicker接受的答案当然是正确的方法。 但是,我想提出一些建议,而不是 for numpy数组的循环。 我建议您使用向量化解决方案,因为您绝对可以提高性能。 对我来说,这就是使用numpy的方式。

我要做的是使用numpy.split将图像分成单独的通道,然后独立检查每个通道。 我们分配一个与通道之一大小相同的蒙版,并且对于图像中的每个位置,如果任何一个通道都不为零,则将该位置标记为True 此操作的结果将是一个掩码,其中True表示非零像素,否则为False 您可以使用numpy.logical_or ,但是标准语法仅接受两个输入。 如果要在多个输入(即大于2)上使用它,则需要使用reduce惯用语。

找到该蒙版之后,请使用numpy.nonzero确定蒙版中非零或True ,并创建一个最初为全零的输出图像,然后将红色通道设置为255,以与这些对应非零位置。

换句话说:

import numpy as np
import cv2

img = cv2.imread('second.png') # read in image

# Look at each channel independently and see if there are any non-zero pixels
# and merge them together to create a mask
mask = np.logical_or.reduce(np.split(img, 3, axis=2))

# Find those locations in the mask that are non-zero
(rows, cols, _) = np.nonzero(mask)

# Create a blank image, then set the red channel to 255 for those non-zero locations
out = np.zeros(img.shape).astype('uint8')
out[rows,cols,2] = 255

# Show image, wait for key, then close window after
cv2.imshow('Red', out)
cv2.waitKey(0)
cv2.destroyAllWindows()

我们得到这个:

在此处输入图片说明

完全由您决定要执行的操作,但是(对我来说)以上内容更像Python。 使用最舒适的东西!

暂无
暂无

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

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