24ビットカラー図と8ビットのグレースケール図
まず、24ビットのカラー画像を紹介しましょう。 24ビットのカラー画像では、各ピクセルは通常RGBとして表される3バイトで表されます。一般に、多くの24ビットのカラー画像は32ビット画像として保存され、ピクセルあたりの過剰なバイトはalpha値として保存され、特別な影響情報を表示します[1]。
RGBモデルでは、r = g = bの場合、色はグレースケール色を表し、r = g = bの値はグレースケール値と呼ばれます。したがって、グレースケール画像の各ピクセルは、グレースケール値(強度値と輝度値とも呼ばれる)を保存するために1つのバイトのみを必要とし、グレースケールの範囲は0-255です[2]。これにより、写真のグレースケール写真が表示されます。
グレースケールのいくつかの方法
1。コンポーネント方法: 3つのRGBコンポーネントのいずれかをグレースケールマップのグレースケール値として使用します。
2.ほとんどの値方法: 3つのRGBコンポーネントの最大値または最小値をグレースケールマップのグレースケール値として使用します。
3。平均方法: 3つのRGBコンポーネントの平均値をグレースケールグラフのグレースケール値として使用します。
4。重み付け方法:人間の目の色感受性が異なるため、RGB 3コンポーネントの加重平均は、より合理的なグレースケール画像を得ることができます。一般的な状況は次のとおりです。y= 0.30r + 0.59g + 0.11b。
[注]重み付け方法は、実際に写真の輝度値をグレースケール値として計算し、YUVモデルを使用します。 [3]では、著者がy = 0.21 * r + 0.71 * g + 0.07 * bを使用してグレースケール値を計算することがわかります(明らかに3つの重みの合計は1に等しくなく、著者の間違いはありますか?)。実際、この違いは、ガンマ補正が使用されるかどうかに関連している必要があります[1]。
Javaにグレースケールを実装する方法
「JavaはGrayscaleを実装する」を検索する場合、それらのほとんどは1つの方法(コード)です。
public void grayimage()throws ioexception {file file = new file(system.getProperty( "user.dir")+"/test.jpg"); bufferedimage image = imageio.read(file); int width = image.getWidth(); int height = image.getheight(); bufferedimage grayimage = new BufferedImage(幅、高さ、bufferedimage.type_byte_gray); for(int i = 0; i <width; i ++){for(int j = 0; j <height; j ++){int rgb = image.getrgb(i、j); GrayImage.setRgb(i、j、rgb); }} file newFile = new File(system.getProperty( "user.dir")+"/method1.jpg"); Imageio.write(grayimage、 "jpg"、newfile); }test.jpgの元の画像は次のとおりです。
上記の方法を使用して取得したグレースケール図:
このグレイスケールの画像を見ることは実現可能であるように思われますが、 opencvを使用してグレースケールを達成するか、PIL(Python)を使用する場合、効果は大きく異なることがわかります。
img = cv2.imread( 'test.jpg'、cv2.imread_color)gray = cv2.cvtcolor(img、cv2.color_bgr2gray)cv2.imwrite( 'pythonmethod.jpg'、gray)
opencvを使用して取得したグレースケールグラフ(PILに同じことがPILに当てはまる)は、上記のJavaメソッドで得られた方法よりもはるかに優れており、多くの詳細を見ることができます。これは、インターネット上のこの人気のある方法には常にいくつかの問題があることを示していますが、無視されています。
OpenCVでグレースケールを達成する方法
opencvに関連する本やコードを読んだ場合、 opencv Grayscaleが重み付け方法を使用していることをおそらく知っているでしょう。その理由は、 opencv Grayscale画像が非常に良い理由がわからないからです。私たちが無視する他の処理の詳細はありますか?
推測を確認するのは非常に簡単です。ピクセル値がグレーアウトされる前後の変更を確認してください。次のようにテストできます。
img = cv2.imread( 'test.jpg'、cv2.imread_color)h、w = img.shape [:2] gray = cv2.cvtcolor(img、cv2.color_bgr2gray)for J in Range(w):for i in range(h):print str(i) + " +" + " +" + " +" IMG [H-1] [W-1] [0:3]
以下の非常に多くのピクセルを判断することは困難ですが、最後のピクセルポイントに注意を払う必要があり、手がかりを見つけることができます。元の画像の最後のピクセルポイントのRGB値は44、67、89、グレー化後の値は71です。以前にJavaで灰色になった画像のピクセル値を確認すると、ピクセル値がこの式を満たしていないだけでなく、互いに遠くさえしていることがわかります。
この時点で、OpenCV(PILを含む)は、重み付け方法を使用したグレースケールの実装であると推測します。
Javaは加重方法グレースケールを実装します
インターネット上のその人気のある方法が機能しない場合、Grayscaleを達成するためにJavaをどのように使用する必要がありますか?実際、[3]は(複数の方法)グレースケールを成功裏に達成しました(外国人の友人はまだテクノロジーが非常に強力です)、ここでは必要なコードのみが抽出されます。
private static int colortorgb(int alpha、int red、int green、int blue){int newpixel = 0; newPixel += alpha; newPixel = newPixel << 8; newPixel += Red; newPixel = newPixel << 8; newpixel += green; newPixel = newPixel << 8; newPixel += blue; newpixelを返します。 } public static void main(string [] args)throws ioexception {bufferedimage bufferedimage = imageio.read(new File(system.getProperty( "user.dir" + "/test.jpg")); bufferedimage grayimage = new befferedimage(bufferedimage() bufferedimage.getType()); 0xff&0xff =(0.3 * g + 0.11 *); file(system.getProperty( "user.dir") + "/ok.jpg");上記のコードは、グレーのスケールのピクセル値を印刷します。上記のPythonコードと比較すると、ピクセル値が完全に対応していることがわかります。 colorToRGBメソッドは、カラー図を正確に4バイトで処理します。その1つはalphaパラメーターです(前述のとおり)。次の図は、このコードのグレースケール画像です。
他の方法では、同じことを順番に取得できます。
要約します
この記事の理由は、Javaを使用していくつかのグレースケール操作を実装し、OpenCVを使用してコンバージョンの正しいか間違っているかを検証するためです。ただし、実際のテストでいくつかの問題が見つかりました(変換された写真には違いがあり、変換後のグレースケール値に基づいてグレースケールの画像を生成する方法)、これには思考と検証が行われました。ここでは、インターネット上のいくつかの記事には多かれ少なかれさらに考えられていることに注意する必要があります(そして、それらの多くは、特に国内記事さえコピーされています)。これらの実際的な問題については、実践的な実装と検証は非常に重要な方法です。この記事の内容がすべての人に役立つことを願っています。ご質問がある場合は、メッセージを残して話し合ってください。