web-dev-qa-db-ja.com

OpenCV画像を白黒に変換する

グレースケールのOpenCV画像を白黒に変換するにはどうすればよいですか? 類似の質問 がすでに尋ねられているのがわかりますが、OpenCV 2.3を使用していますが、提案されたソリューションはもはや機能していないようです。

私はグレースケール画像を白黒に変換しようとしているので、絶対に黒ではないものはすべて白になり、これを surf.detect() のマスクとして使用して、上のキーポイントを無視しますブラックマスク領域のエッジ。

次のPythonでほぼそこに到達しますが、Threshold()に送信されるしきい値は効果がないようです。0または16または128または255に設定すると、結果は値が128より大きいすべてのピクセルが白になり、他のすべてのピクセルが黒になります。

何が間違っていますか?

import cv, cv2
fn = 'myfile.jpg'
im_gray = cv2.imread(fn, cv.CV_LOAD_IMAGE_GRAYSCALE)
im_gray_mat = cv.fromarray(im_gray)
im_bw = cv.CreateImage(cv.GetSize(im_gray_mat), cv.IPL_DEPTH_8U, 1);
im_bw_mat = cv.GetMat(im_bw)
threshold = 0 # 128#255# HAS NO EFFECT!?!?
cv.Threshold(im_gray_mat, im_bw_mat, threshold, 255, cv.CV_THRESH_BINARY | cv.CV_THRESH_OTSU);
cv2.imshow('', np.asarray(im_bw_mat))
cv2.waitKey()
44
Cerin

新しいcv2 Pythonバインディングを使用して、参照するものと同様の段階的な回答:

1。グレースケール画像を読み取る

import cv2
im_gray = cv2.imread('grayscale_image.png', cv2.IMREAD_GRAYSCALE)

2。グレースケール画像をバイナリに変換

(thresh, im_bw) = cv2.threshold(im_gray, 128, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)

otsuの方法を使用して画像から自動的にしきい値を決定するか、既にしきい値を知っている場合は使用できます。

thresh = 127
im_bw = cv2.threshold(im_gray, thresh, 255, cv2.THRESH_BINARY)[1]

。ディスクに保存

cv2.imwrite('bw_image.png', im_bw)
85
tsh

CV_THRESH_OTSUを指定すると、しきい値が無視されます。 ドキュメント から:

また、特別な値THRESH_OTSUは、上記の値のいずれかと組み合わせることができます。この場合、関数はOtsuのアルゴリズムを使用して最適なしきい値を決定し、指定されたthreshの代わりにそれを使用します。この関数は、計算されたしきい値を返します。現在、大津の方法は8ビット画像に対してのみ実装されています。

このコードは、カメラからフレームを読み取り、値20でバイナリしきい値を実行します。

#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"

using namespace cv;

int main(int argc, const char * argv[]) {

    VideoCapture cap; 
    if(argc > 1) 
        cap.open(string(argv[1])); 
    else 
        cap.open(0); 
    Mat frame; 
    namedWindow("video", 1); 
    for(;;) {
        cap >> frame; 
        if(!frame.data) 
            break; 
        cvtColor(frame, frame, CV_BGR2GRAY);
        threshold(frame, frame, 20, 255, THRESH_BINARY);
        imshow("video", frame); 
        if(waitKey(30) >= 0) 
            break;
    }

    return 0;
}
8
SSteve

アプローチ1

グレースケール画像をバイナリ画像に変換する際、通常はcv2.threshold()を使用し、手動でしきい値を設定します。適切な結果を得るために、Otsuの二値化を選択することもあります。

ブログの投稿を読んでいる間に出会った小さなハックがあります。

  1. カラー(RGB)画像をグレースケールに変換します。
  2. グレースケール画像の中央値を取得します。
  3. 中央値より33%高いしきい値を選択します

enter image description here

なぜ33%ですか?

これは、33%がほとんどの画像/データセットで機能するためです。

medianmeanに置き換えることにより、同じアプローチを実行することもできます。

アプローチ2

別のアプローチは、正または負のいずれかで、平均からx個の標準偏差(std)を取ることです。しきい値を設定します。したがって、次のいずれかになります。

  • th1 = mean - (x * std)
  • th2 = mean + (x * std)

注:しきい値を適用する前に、グレースケール画像のコントラストを強調することをお勧めしますlocally(参照 [〜#〜] clahe [〜#〜] )。

5
Jeru Luke

次のコードスニペットを書くだけで、OpenCVイメージをグレースケールイメージに変換できます。

import cv2
image = cv2.imread('image.jpg',0)
cv2.imshow('grey scale image',image)

Image.jpgとコードを同じフォルダーに保存する必要があることに注意してください。

ご了承ください:

  • ('image.jpg')はRGB画像を与えます
  • ('image.jpg',0)はグレースケール画像を提供します。
5
Ananth Reddy

_cv.CV_THRESH_BINARY_を使用する場合、しきい値を超えるすべてのピクセルがmaxValue(255の場合)になることを意味します。それ以外の場合、値は0です。値が255の場合、すべてが黒になります(つまり0)。

しきい値を計算したくない場合は、大津の方法を使用できます。ただし、このアルゴリズムはOpenCVの実装で8ビット画像でのみ機能します。画像が8ビットの場合、次のようなアルゴリズムを使用します。

cv.Threshold(im_gray_mat, im_bw_mat, threshold, 255, cv.CV_THRESH_BINARY | cv.CV_THRESH_OTSU);

8ビット画像の場合、しきい値の値に関係なく。

1
javier

これはオンラインで見つけた初心者向けの2行のコードです

# Absolute value of the 32/64
abs_image_in32_64 = np.absolute(image_in32_64)

image_8U = np.uint8(abs_image_in32_64)
1
Santhosh

ビデオをやっている人のために、私は@tshに基づいて次のことを考えました。

import cv2 as cv
import numpy as np

def nothing(x):pass

cap = cv.VideoCapture(0)
cv.namedWindow('videoUI', cv.WINDOW_NORMAL)
cv.createTrackbar('T','videoUI',0,255,nothing)

while(True):
    ret, frame = cap.read()
    vid_gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
    thresh = cv.getTrackbarPos('T','videoUI');
    vid_bw = cv.threshold(vid_gray, thresh, 255, cv.THRESH_BINARY)[1]

    cv.imshow('videoUI',cv.flip(vid_bw,1))

    if cv.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv.destroyAllWindows()

結果:

enter image description here

0
Keno