OpenCV:着色失败

时间:2015-03-16 10:44:58

标签: python image opencv image-processing numpy

我正在阅读图像,我想将所有非零像素着色为红色。此外,背景由黑色组成。我写的尝试执行此操作的代码如下所示:

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

enter image description here

以下是彩色图片 result.png

enter image description here

为什么有些像素没有变成红色?请注意,当我在second.png中打印result.png中不是红色的那些位置的颜色像素值时,我发现它们不是黑色。

有谁知道为什么会这样?

3 个答案:

答案 0 :(得分:1)

您应该在条件中使用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):写为条件,这是等效的。

答案 1 :(得分:1)

如果您只想留下阅读频道,可以使用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;
}

结果:

答案 2 :(得分:1)

David Zwicker接受的答案肯定是要走的路。但是,我想建议一些内容,并且使用for循环和numpy数组。我建议使用矢量化解决方案,因为你肯定会获得性能提升。对我来说,这就是numpy的用法。

我要做的是将图像分割为numpy.split的单独通道,然后单独检查每个通道。我们为其中一个频道分配了相同大小的掩码,如果任何频道非零,我们会将此位置标记为{{1} }。此操作的结果将是掩码,其中True表示非零像素,否则为True。您可以使用numpy.logical_or,但标准语法只接受两个输入。如果您想在多个输入(即大于2)上使用此输入,则需要使用reduce惯用法。

找到此掩码后,使用numpy.nonzero确定掩码中非零或False的位置,并创建一个最初全为零的输出图像,然后将红色通道设置为255,对应于这些非零位置。

或换句话说:

True

我们得到了这个:

enter image description here

完全取决于你想要做什么,但上面(对我而言)更像是Pythonic。使用你最熟悉的任何东西!