簡體   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