web-dev-qa-db-ja.com

OpenCV(Python)で、グレースケール画像から3チャンネル画像を取得するのはなぜですか?

私はPython(2.7)とUbuntu 12.04のOpenCV 2.4.6のバインディングを使用しています

画像を読み込む

    image = cv2.imread('image.jpg')

次に、画像配列の形状を確認します

    print image.shape

私は(480、640、3)を取得しますが、これは640x480のカラー画像に必要です。次に、画像をグレースケールに変換し、形状を再度確認します。

    gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    print gray_image.shape

私は(480、640、1)を取得しますが、これは640x480 グレースケール画像に期待しています。次に、画像を保存します。

    cv2.imwrite('gray.jpg', gray_image)

私はLinuxを使用しているので、すべてのカラーチャンネルを表示するgThumbで画像を見てみました。グレーの画像をOpenCVに戻すと、画像には再び3つのチャネルがあります。私は画像を読むためのこのフラグを知っています:

    CV_LOAD_IMAGE_GRAYSCALE - If set, always convert image to the grayscale one

しかし、これは画像をカラー画像として取り込み、変換するように聞こえます。このプロジェクトをRaspberryPiに移植しているので、不必要な操作が発生しないようにします。

編集:タイミングチェックをいくつか行ったところ、CV_LOAD_IMAGE_GRAYSCALEフラグセットを使用して画像を読み込むと、画像の入力に関係なく2倍の速度で画像が読み込まれることがわかりました。

     Using a 3072 x 4608 x 3 image
     0.196774959564 seconds with default loading
     0.0931899547577 seconds with CV_LOAD_IMAGE_GRAYSCALE

問題は、グレースケールイメージマトリックスがあるかどうかに関係なく、OpenCVが3チャンネルのJPG出力を作成しているようです!

単一の8ビットチャンネルJPG画像を確実に出力するために、他にどのアプリを使用できますか?? (おそらく、gThumbはチャネルを誤って報告しています)。

画像が単一チャンネルではない場合、OpenCVがディスク書き込み時にグレースケール画像を3チャンネル画像に保存するのはなぜですか?

前もって感謝します。

32
Steve

あなたのコードは正しいです。cv2.imreadが設定されていない限り、CV_LOAD_IMAGE_GRAYSCALEは3つのチャネルで画像をロードしているようです。

>>> import cv2
>>> image = cv2.imread('foo.jpg')
>>> print image.shape
 (184, 300, 3)
>>> gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
>>> print gray_image.shape 
 (184, 300)
>>> cv2.imwrite('gray.jpg', gray_image)

画像をロードする場合:

>>> image = cv2.imread('gray.jpg')
>>> print image.shape
 (184, 300, 3)

画像をBGRとして保存したようですが、実際はopencvであり、デフォルトでは3チャンネルで画像を読み取り、グレースケールの場合はレイヤーを3回コピーします。 scipyで画像を再度ロードすると、画像が実際にグレースケールであることがわかります。

>>> from scipy.ndimage import imread
>>> image2 = imread('gray.jpg')
>>> print image2.shape
 (184, 300)

したがって、グレースケール画像をロードする場合は、CV_LOAD_IMAGE_GRAYSCALEフラグを設定する必要があります。

>>> image = cv2.imread('gray.jpg', cv2.CV_LOAD_IMAGE_GRAYSCALE)
>>> print image.shape
 (184, 300)
39
jabaldonedo

これを試して:

 img = cv2.imread('gray.jpg',0)

グレーの場合1カラーの場合

13
Jino

OpenCVでjpg画像を読み込むと、デフォルトで3チャンネル画像が生成されます。したがって、jpgファイルから実際にグレースケールされていることを実際に確認できるかどうかはわかりませんが、いつでもグレースケールとして読み込むことができます。画像が事前にグレースケールされていない場合にのみ問題が発生し、あなたの場合はそれが機能しないと信じています。短い答え:jpgをonechanneled画像として保存することはできません。そのため、読み取り後に再度グレースケールするか、画像がグレースケールかどうかを判断する新しい方法を見つけ出す必要があります。

1
Henri Korhonen