グレースケールの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()
新しい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)
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;
}
グレースケール画像をバイナリ画像に変換する際、通常はcv2.threshold()
を使用し、手動でしきい値を設定します。適切な結果を得るために、Otsuの二値化を選択することもあります。
ブログの投稿を読んでいる間に出会った小さなハックがあります。
これは、33%がほとんどの画像/データセットで機能するためです。
median
をmean
に置き換えることにより、同じアプローチを実行することもできます。
別のアプローチは、正または負のいずれかで、平均からx
個の標準偏差(std
)を取ることです。しきい値を設定します。したがって、次のいずれかになります。
th1 = mean - (x * std)
th2 = mean + (x * std)
注:しきい値を適用する前に、グレースケール画像のコントラストを強調することをお勧めしますlocally(参照 [〜#〜] clahe [〜#〜] )。
次のコードスニペットを書くだけで、OpenCVイメージをグレースケールイメージに変換できます。
import cv2
image = cv2.imread('image.jpg',0)
cv2.imshow('grey scale image',image)
Image.jpgとコードを同じフォルダーに保存する必要があることに注意してください。
ご了承ください:
('image.jpg')
はRGB画像を与えます('image.jpg',0)
はグレースケール画像を提供します。_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ビット画像の場合、しきい値の値に関係なく。
これはオンラインで見つけた初心者向けの2行のコードです
# Absolute value of the 32/64
abs_image_in32_64 = np.absolute(image_in32_64)
image_8U = np.uint8(abs_image_in32_64)
ビデオをやっている人のために、私は@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()
結果: