65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 10 种编程语言进行图像二值化

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.92/5 (18投票s)

2016年4月20日

CPOL

3分钟阅读

viewsIcon

96492

downloadIcon

2081

一个简单的图像二值化

引言

有时,我们需要将彩色图像转换为黑白图像。 例如,黑白传真机和复印机都需要将彩色图像转换为黑白图像。 为此,有几种方法,例如二值化和抖动,每种方法都包含几种变体。 前者包括日本发明的用于自动阈值的Otsu方法和最简单的固定阈值方法。

在本文中,我们首先要学习如何处理图像,因此使用了固定阈值方法。 最重要的是学习如何将图像文件读入并处理其中的像素数据。 我们尝试提供尽可能多的编程语言,以便不同的设计人员可以了解如何处理像素数据。 本文提供的编程语言包括 Visual C++ 2010、C++ Builder XE5、Visual C# 2012、Visual Basic .NET 2012、Visual Basic 6.0、JAVA with NetBeans v8.1、DELPHI XE5、Android v4.1.2 with Eclipse、HTML5 + JavaScript 和 Matlab 2011。 作者认为,学习数字图像处理与编程语言无关。 最重要的是学习数字图像处理的知识,因为编程语言只是一种帮助您实现此目标的工具,而不是关键。 因此,作者通过以十种不同的方式演示相同的算法来树立榜样。 目的是证明数字图像处理与编程语言关系不大。

为了使读者能够理解,本文中的所有程序示例都附有英文注释,以便读者不仅可以理解,还可以轻松阅读代码。 如果您有这些开发工具,则可以打开附带的源代码。 无论您选择编译还是解释它们,您都可以运行单步调试来逐步检查算法的计算过程。 或者,您可以在重要的部分或您不理解的部分设置断点,以便程序将停止并等待,直到您检查了所有变量的已保存值。 最重要的是熟悉这种二值化算法,因为它是数字图像处理技术中一种更简单的算法,并且不包含任何晦涩的数学公式。 它只需要设置阈值,然后比较大小以确定黑色或白色。 关键在于如何处理像素和计算像素的索引。

Using the Code

Visual C++ 2010

Visual C++ 2010

// The height of the image.
for ( int iY = 0; iY < imageA->DibInfo->bmiHeader.biHeight; iY++ )
{
    // The width of the image.
    for ( int iX = 0; iX < imageA->DibInfo->bmiHeader.biWidth; iX++ )
    {
        // The index of pixel, because we use the three depth bit to present one pixel of color.
        // Therefore, we have to multiple three.
        lIDXA = ( iX * 3 ) + ( iY * imageA->DibInfo->bmiHeader.biWidth * 3 );
        // To get the pixel depth of the blue channel.
        byteRGB_BA = imageA->DibArry[lIDXA+0];
        // To get the pixel depth of the green channel.
        byteRGB_GA = imageA->DibArry[lIDXA+1];
        // To get the pixel depth of the red channel.
        byteRGB_RA = imageA->DibArry[lIDXA+2];
        // To transform RGB to Y (gray scale).
        dobYUV_YA =  (0.299 * byteRGB_RA + 0.587 * byteRGB_GA + 0.114 * byteRGB_BA);
        // Set our thresholds, To decide which pixel become to white.
        if ( dobYUV_YA > 60 && dobYUV_YA < 160 )
        {
            lIDXB = ( iX * 3 ) + ( iY * imageB->DibInfo->bmiHeader.biWidth * 3 );
            imageB->DibArry[lIDXB+0] = 255;
            imageB->DibArry[lIDXB+1] = 255;
            imageB->DibArry[lIDXB+2] = 255;
        }
        // Otherwise, those pixels will be black.
        else
        {
            lIDXB = ( iX * 3 ) + ( iY * imageB->DibInfo->bmiHeader.biWidth * 3 );
            imageB->DibArry[lIDXB+0] = 0;
            imageB->DibArry[lIDXB+1] = 0;
            imageB->DibArry[lIDXB+2] = 0;
        }
    } // for ( int iX = 0; iX < imageA->DibInfo->bmiHeader.biWidth; iX++ )
} // for ( int iY = 0; iY < imageA->DibInfo->bmiHeader.biHeight; iY++ )

C++ Builder XE5

C++ Builder XE5

C++ Builder XE5

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
// Create three points of TBitmap object
Graphics::TBitmap *TheBitmap, *TempBitmap, *OriginBitmap;
// Create a threshold.
int Threshold;

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Exit1Click(TObject *Sender)
{
	// Exit the program
	Close();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::OpenFile1Click(TObject *Sender)
{
	// If you got a file of the picture, you are able to load it.
	if ( OpenPictureDialog1->Execute() )
	{
		// Disable automatic resize.
		Image1->AutoSize=false;
		// Enable an automatic stretch.
		Image1->Stretch=true;
		// Loads a picture file.
		Image1->Picture->LoadFromFile(OpenPictureDialog1->FileName);
		// Set a point to the picture of loading.
		TheBitmap=Image1->Picture->Bitmap;
		// Create a new TBitmap object to keep original picture.
		OriginBitmap = new Graphics::TBitmap();
		// To keep original picture.
		OriginBitmap->Assign(TheBitmap);
		// Set up TImage object to keep original picture.
		Image1->Picture->Bitmap->Assign(TheBitmap);
		// If you open picture file successful and then set a flag.
		// The means that you have been opened a file.
		OpenFile = 1;
		// Set the threshold is 100.
		Threshold = 100;
		// Set the position of the scroll bar is 100.
		ScrollBar1->Position = Threshold;
	}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ScrollBar1Change(TObject *Sender)
{
	// If you have not opened a file, the flag will be zero, and then returns.
	if (OpenFile == 0) {
		return;
	}
	Byte *ptr, *tptr;
	// To get a counter of binarization from the scroll bar.
	Threshold = (int) ScrollBar1->Position;
	// Set up the TImage restore to the original picture.
	Image1->Picture->Bitmap->Assign(OriginBitmap);
	// To do the times of binarization
	TempBitmap = new Graphics::TBitmap();
	// To get a current bitmap.
	TempBitmap->Assign(TheBitmap);
	// To do scan line of the whole picture.
	for (int y=0; y < TheBitmap->Height; y++) {
		// Set Y position of the image point.
		ptr = (Byte*) TheBitmap->ScanLine[y];
		// Set Y position of the image point.
		tptr = (Byte*) TempBitmap->ScanLine[y];
		// To do scan X-axis of the line.
		for (int x=0; x < TheBitmap->Width; x++) {
			// if the pixel more than the threshold, it should be white.
			if (tptr[x] > Threshold) {
				ptr[x] = (Byte) 255;
			}
			// Otherwise, it should be black.
			else
			{
				ptr[x] = (Byte) 0;
			}
		} // End x
	} // End y
	// Release the temporal bitmap.
	delete TempBitmap;
	// Refresh and draw the TImage object
	Repaint();
	// Set result of binarization of the picture.
	Image1->Picture->Bitmap->Assign(TheBitmap);
}
//---------------------------------------------------------------------------

Visual C Sharp 2012

Visual C Sharp 2012

正常

namespace Binarization_for_C_Sharp
{
    public partial class Form1 : Form
    {
        // This is a file name string.
        private string curFileName;
        // This is a bitmap object.
        private System.Drawing.Bitmap curBitmap;

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            // Establish a open file dialog.
            OpenFileDialog openDlg = new OpenFileDialog();
            // Set a filter to arrange picture format.
            openDlg.Filter = "All format | *.bmp; *.pcx; *.png; *.jpg; *.gif;" +
                "*.tif; *.ico; *.dxf; *.cgm; *.cdr; *.wmf; *.eps; *.emf";
            // Set the title of the open file dialog.
            openDlg.Title = "Open a picture file.";
            // if open file is successful.
            if (openDlg.ShowDialog() == DialogResult.OK)
            {
                // Get the open file name to current file name variable.
                curFileName = openDlg.FileName;
                try
                {
                    // Establish a bitmap from file through by Image object.
                    curBitmap = (Bitmap)Image.FromFile(curFileName);
                }
                // If we get a exception.
                catch (Exception exp)
                {
                    // Pop to a message.
                    MessageBox.Show(exp.Message);
                }
            }
            // Force to redraw.
            Invalidate();
        }

        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            // Establish a graphics object from external object
            Graphics g = e.Graphics;
            // if it is to open file successful.
            if (curBitmap != null)
            {
                // Draw the picture in the position that we set up.
                g.DrawImage(curBitmap, 140, 10, curBitmap.Width, curBitmap.Height);
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            // if it is to open file successful.
            if (curBitmap != null)
            {
                // Establish a color object.
                Color curColor;
                int ret;
                // The width of the image.
                for (int iX = 0; iX < curBitmap.Width; iX++)
                {
                    // The height of the image.
                    for ( int iY = 0; iY < curBitmap.Height; iY++ )
                    {
                        // Get the pixel from bitmap object.
                        curColor = curBitmap.GetPixel(iX, iY);
                        // Transform RGB to Y (gray scale)
                        ret = (int) (curColor.R * 0.299 + curColor.G * 0.578 + curColor.B * 0.114);
                        // This is our threshold, you can change it and to try what are different.
                        if (ret > 120)
                        {
                            ret = 255;
                        }
                        else
                        {
                            ret = 0;
                        }
                        // Set the pixel into the bitmap object.
                        curBitmap.SetPixel( iX, iY, Color.FromArgb ( ret, ret ,ret ) );
                    } // The closing 'The height of the image'.
                } // The closing 'The width of the image'.
                // Force to redraw.
                Invalidate();
            }
        }
    }
}

快速

        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            // Establish a graphics object from external object
            Graphics g = e.Graphics;
            // if it is to open file successful.
            if (curBitmap != null)
            {
                // Red
                int iR = 0;
                // Green
                int iG = 0;
                // Blue
                int iB = 0;

                // Lock the bitmap's bits.  
                Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
                System.Drawing.Imaging.BitmapData bmpData =
                    curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite,
                    curBitmap.PixelFormat);

                // Get the address of the first line.
                IntPtr ptr = bmpData.Scan0;

                // Declare an array to hold the bytes of the bitmap.
                int bytes = Math.Abs(bmpData.Stride) * curBitmap.Height;
                byte[] rgbValues = new byte[bytes];

                // Copy the RGB values into the array.
                System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);

                // Set every third value to 255. A 24bpp bitmap will binarization.  
                for (int counter = 0; counter < rgbValues.Length; counter += 3)
                {
                    // Get the red channel
                    iR = rgbValues[counter + 2];
                    // Get the green channel
                    iG = rgbValues[counter + 1];
                    // Get the blue channel
                    iB = rgbValues[counter + 0];
                    // If the gray value more than threshold and then set a white pixel.
                    if ((iR + iG + iB) / 3 > 100)
                    {
                        // White pixel
                        rgbValues[counter + 2] = 255;
                        rgbValues[counter + 1] = 255;
                        rgbValues[counter + 0] = 255;
                    }
                    else
                    {
                        // Black pixel
                        rgbValues[counter + 2] = 0;
                        rgbValues[counter + 1] = 0;
                        rgbValues[counter + 0] = 0;
                    }
                }

                // Copy the RGB values back to the bitmap
                System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes);

                // Unlock the bits.
                curBitmap.UnlockBits(bmpData);

                // Draw the modified image.
                g.DrawImage(curBitmap, 140, 10, curBitmap.Width, curBitmap.Height);
            }
        }

Visual Basic .NET 2012

Visual Basic .NET 2012

Public Class Form1
    ' Establish a string of the current file name
    Private curFileName As String
    ' Establish a bitmap object of current bitmap object
    Private curBitmap As Bitmap

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        ' Establish a open file dialog.
        Dim openFileDialog1 As New OpenFileDialog()
        ' The initial directory displayed by the file dialog box. The default is an empty string ("").
        openFileDialog1.InitialDirectory = ".\"
        ' The file filtering options available in the dialog box.
        openFileDialog1.Filter = "All format | *.bmp; *.pcx; *.png; *.jpg; *.gif;" +
                "*.tif; *.ico; *.dxf; *.cgm; *.cdr; *.wmf; *.eps; *.emf"
        ' A value containing the index of the filter currently selected in the file dialog box. 
        ' The default value is 1.
        openFileDialog1.FilterIndex = 1
        ' true if the dialog box restores the current directory to its original value 
        ' if the user changed
        ' the directory while searching for files; otherwise, false. The default value is false.
        openFileDialog1.RestoreDirectory = True
        ' If the open file is successful.
        If openFileDialog1.ShowDialog() = System.Windows.Forms.DialogResult.OK Then
            Try
                ' Set the file name into current file name.
                curFileName = openFileDialog1.FileName
                ' Make sure the file is not empty.
                If (curFileName IsNot Nothing) Then
                    ' Establish a bitmap from file through by Image object.
                    Dim b As Bitmap = New Bitmap(curFileName)
                    ' Establish a bitmap object from the loaded image of bitmap object.
                    curBitmap = New Bitmap(b.Width, b.Height, _
			System.Drawing.Imaging.PixelFormat.Format32bppPArgb)
                    ' Clone the bitmap object
                    curBitmap = b.Clone()
                End If
                ' If we have a problem, throw a exception and pop up a message.
            Catch Ex As Exception
                MessageBox.Show("Cannot read file from disk. Original error: " & Ex.Message)
            Finally
                ' Check this again, since we need to make sure we didn't throw an exception on open.
            End Try
            ' Force to redraw.
            Invalidate()
        End If
    End Sub

    Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles MyBase.Paint
        ' if it is to open file successful.
        If (curBitmap IsNot Nothing) Then
            ' Draw the picture in the position that we set up.
            e.Graphics.DrawImage(curBitmap, 140, 10, curBitmap.Width, curBitmap.Height)
        End If
    End Sub

    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
        ' The height of the image.
        For y As Integer = 0 To curBitmap.Height - 1
            ' The width of the image.
            For x = 0 To curBitmap.Width - 1
                ' Get the pixel from current bitmap object.
                Dim curPixColor As Color = curBitmap.GetPixel(x, y)
                ' This is a gray variable.
                Dim ret As Integer
                ' Transform RGB color space to Y (gray scale)
                ret = (curPixColor.R * 0.299 + curPixColor.G * 0.578 + curPixColor.B * 0.114)
                ' This is our threshold, you can change it.
                If ret > 120 Then
                    curBitmap.SetPixel(x, y, Color.White)
                Else
                    curBitmap.SetPixel(x, y, Color.Black)
                End If
                ' The closing 'The width of the image'.
            Next
            ' The closing 'The height of the image'.
        Next
        ' Force to redraw.
        Invalidate()
    End Sub
End Class

Visual Basic 6.0

Visual Basic .NET 2012

' The Form loading
Private Sub Form_Load()
    ' Loading a bitmap
    Picture1.Picture = LoadPicture(App.Path & "\B_01.bmp")
    ' The variable is X-axis
    Dim lngX As Long
    ' The variable is Y-axis
    Dim lngY As Long
    ' The variable is gray
    Dim intS
    ' The variable is RGB, respectively.
    Dim intR, intG, intB
    ' Set up the scale mode is pixel.
    Picture1.ScaleMode = 3
    ' Enable the picture box autometic redraw.
    Picture1.AutoRedraw = True
    ' Set up the scale mode is pixel.
    Picture2.ScaleMode = 3
    ' Enable the picture box autometic redraw.
    Picture2.AutoRedraw = True
    ' The height of the image
    For lngY = 0 To Picture1.ScaleHeight
        ' The width of the image
        For lngX = 0 To Picture1.ScaleWidth
            ' Get the pixel of the red channel
            intR = (Picture1.Point(lngX, lngY) And &HFF)
            ' Get the pixel of the green channel
            intG = (Picture1.Point(lngX, lngY) And &HFF00&) \ 256
            ' Get the pixel of the blue channel
            intB = (Picture1.Point(lngX, lngY) And &HFF0000) \ 65536
            ' Make a gray scale pixel
            intS = (intR + intG + intB) / 3
            ' This is our threshold, if it over 120, it should be white.
            If intS > 120 Then
               intS = 255
            ' Otherwise, it should be black.
            Else
               intS = 0
            End If
            ' Set the monochromatic pixel.
            Picture2.PSet (lngX, lngY), RGB(intS, intS, intS)
        ' The closing 'The width of the image'.
        Next lngX
    ' The closing 'The height of the image'.
    Next lngY
End Sub

JAVA for NetBeans v8.0.2

JAVA for NetBeans v8.0.2

import java.awt.FileDialog;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.io.File;
import java.io.IOException;
import java.awt.image.DataBufferByte;

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
       FileDialog f = new FileDialog(this, "Open File", FileDialog.LOAD);
       // Set the default directory
       f.setDirectory(".");
       // Display the dialog and wait for the user's response
       f.show();
       // Remember new default directory.
       String directory = f.getDirectory();
       // Establish a full path.
       String filepath = directory+f.getFile();
       // Establish an image object from BufferedImage.
       BufferedImage img = null;
       try {
           // Read an image from the file.
           img = ImageIO.read(new File(filepath));
           // To do binarization.
           int[][] result = convertToBinarization(img);
           // Show a processed image.
           jLabel1.setIcon(new javax.swing.ImageIcon(img));
       }
       // We have a problem and then throw an exception.
       catch (IOException e) {
           System.err.println("I could not load the file \'"+directory+"'.  Sorry.");
       }
}

// This function is to convert RGB image binarization.
private static int[][] convertToBinarization(BufferedImage image) {
    // Get the width of the image.
    int width = image.getWidth();
    // Get the height of the image.
    int height = image.getHeight();
    // Establish a 2D array to keep image data.
    int[][] result = new int[height][width];
    // The height of the image.
    for (int row = 0; row < height; row++) {
        // The width of the image.
        for (int col = 0; col < width; col++) {
            // Acquire RGB value.
            result[row][col] = image.getRGB(row, col);
            // Acqurie integer type of RGB value.
            int iRet = result[row][col];
            // The alpha variable.
            int iA = 0;
            // The red variable.
            int iR = 0;
            // The green variable.
            int iG = 0;
            // The bule variable.
            int iB = 0;
            int iGray = 0;
            // Get the alpha of the alpha channel.
            iA = (((int) iRet & 0xff) << 24);
            // Get blue pixel of the blue channel.
            iB = ((int) iRet & 0xff);
            // Get green pixel of the green channel.
            iG = (((int) iRet & 0x00ff00) >> 8);
            // Get red pixel of the red channel.
            iR = (((int) iRet & 0xff0000) >> 16);
            // Transform RGB color space to gray scale.
            iG = ( iR + iG + iB ) / 3;
            // This is our threshold, you can change it.
            if ( iG > 120 )
            {
                // This is white pixel.
                iRet = 0xffffff;
                // Set the white pixel into the image.
                image.setRGB(row, col, iRet);
            }
            else
            {
                // Set the black pixel into the image.
                image.setRGB(row, col, 0);
            }
      }
  }
  // return result value.
  return result;
}

DELPHI XE5

DELPHI XE5

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtDlgs, Vcl.ExtCtrls;

type
  TForm1 = class(TForm)
    Image1: TImage;
    OpenPictureDialog1: TOpenPictureDialog;
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  // The string variable is a file name.
  Str : String;
implementation

{$R *.dfm}


procedure TForm1.Button2Click(Sender: TObject);
var
  PByte :PByteArray;
  Gray,x,y :Integer;
  ImageBmp :TBitmap;
begin
  // if it is no file name and pop up a message.
  if Str = '' then
    showmessage('Can not open this file, because it is an empty.')
  // Otherwise, There is a file name.
  else
  begin
  // Establish a TBitmap object.
  ImageBmp :=TBitmap.Create;
  // Assign the Image object.
  ImageBmp.Assign(Image1.Picture.Bitmap);
  // Set pixel format is 24 bits.
  ImageBmp.PixelFormat :=pf24Bit;
  // The height of the image.
  for y:=0 to ImageBmp.Height-1 do
  begin
    // Set the point up to Y-axis.
    PByte := ImageBmp.scanline[y];
    // The width of the image.
    for x:=0 to ImageBmp.Width-1 do
    begin
      // Transform RGB color space to gray scale.
      Gray:=Round(PByte[x*3+2]*0.3+PByte[x*3+1]*0.59+PByte[x*3]*0.11);
      // This is our threshold, you can change it. What is a different?
      if Gray > 120 then
      // Set the pixel is white.
      begin
         PByte[x*3]:=255;
         PByte[x*3+1]:=255;
         PByte[x*3+2]:=255;
      end
      // Otherwise, set the pixel is black.
      else
      begin
         PByte[x*3]:=0;
         PByte[x*3+1]:=0;
         PByte[x*3+2]:=0;
      end
    end;
  end;
  // Assign a processed image.
  Image1.Picture.Bitmap.Assign(ImageBmp);
  // Release the TBitmap object.
  ImageBmp.Free;
end;
end;


procedure TForm1.Button1Click(Sender: TObject);
var
  // The string is full path.
  Path:string;
begin
  // Set the path is in the path of the execute file.
  path:=ExtractFilePath(application.ExeName);
  // Set up initial directory.
  OpenPictureDialog1.InitialDir := Path;
  // Execute the OpenPictureDialog object.
  if OpenPictureDialog1.Execute then
  begin
    // Set a file name into str variable.
    Str := OpenPictureDialog1.FileName;
    // Loading a picture from the file.
    Image1.Picture.LoadFromFile(Str);
  end;
end;

end.

Android v4.1.2 with Eclipse

Android v4.1.2 with Eclipse

package com.example.binarization.camera;

import com.example.binarization.camera.R;

import android.os.Bundle;
import android.app.Activity;
import android.view.*;
import android.widget.*;
import android.annotation.SuppressLint;
import android.content.pm.ActivityInfo;
import android.graphics.PixelFormat;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.hardware.Camera;
import android.hardware.Camera.AutoFocusCallback;
import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.PictureCallback;

@SuppressLint("NewApi")
public class MainActivity extends Activity implements SurfaceHolder.Callback  {

	SurfaceView mSurfaceView ;
	Button btn_Capture;
	Camera mCamera;
	PictureCallback mPictureCB;
	AutoFocusCallback mAutoFocusCB;
	ImageView ImgView;
	TextView txtView;
	Bitmap bitmapClone;

	@SuppressWarnings("deprecation")
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		// Set the format of window, as per the PixelFormat types.
		// This overrides the default format that is selected by
		// the Window based on its window decorations.
		// System chooses a format that supports translucency (many alpha bits).
		getWindow().setFormat(PixelFormat.TRANSLUCENT);
		// Enable extended window features.
		// Flag for the "no title" feature, turning off the title at the top of the screen.
	   	requestWindowFeature(Window.FEATURE_NO_TITLE);
	   	// Set the flags of the window, as per the WindowManager.LayoutParams flags.
	   	// Window flag: Hide all screen decorations (e.g. status bar).
	   	// while this window is displayed. This allows the window to use
	   	// the entire display space for itself -- the status bar will be
	   	// hidden when an app window with this flag set is on the top layer.
	   	getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
	   	WindowManager.LayoutParams.FLAG_FULLSCREEN);
        // Set the activity content from a layout resource.
	   	// The resource will be inflated, adding all top-level views to the activity.
	   	setContentView(R.layout.activity_main);
		// Change the desired orientation of this activity.
	   	// If the activity is currently in the foreground or
	   	// otherwise impacting the screen orientation,
	   	// the screen will immediately be changed
	   	// (possibly causing the activity to be restarted).
	   	// Otherwise, this will be used the next time the activity is visible.
        // Constant corresponding to portrait in the android.R.attr.screenOrientation attribute.
   	 	this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
   	 	// -- (Start)
   	 	ImgView = (ImageView)this.findViewById(R.id.ImgView);
   	 	txtView = (TextView)this.findViewById(R.id.txtView);
   	 	btn_Capture = (Button)this.findViewById(R.id.btn_Capture);
   	 	mSurfaceView  = (SurfaceView)this.findViewById(R.id.surView_Camera);
   	 	// -- (End)
   	 	// Set and get SurfaceHolder
   	 	// Abstract interface to someone holding a display surface.
   	 	// Allows you to control the surface size and format,
   	 	// edit the pixels in the surface, and monitor changes to the surface.
   	 	// This interface is typically available through the SurfaceView class.
        // When using this interface from a thread other than the one running
   	 	// its SurfaceView, you will want to carefully read the methods
   	 	// lockCanvas and Callback.surfaceCreated().
   	 	SurfaceHolder mSurfaceHolder = mSurfaceView.getHolder();
   	 	mSurfaceHolder.addCallback(this);
   	 	mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

        // To establish Camera.takePicture callback function.
   	    mPictureCB = new PictureCallback(){
        // Image processing.
   	    // Overwrite onPictureTake function.
   	    @Override
   		public void onPictureTaken(byte[] data, Camera camera){
   	   	    // We use the BitmapFactory to decode become raw data to bitmap format.
   			Bitmap mBitmap = BitmapFactory.decodeByteArray(data, 0 , data.length);
   			bitmapClone = Bitmap.createBitmap(mBitmap.getWidth(), 
					mBitmap.getHeight(), mBitmap.getConfig());
   			bitmapClone.copy(mBitmap.getConfig(), true);
			int iY = 0;
			int iX = 0;
			int iPixel = 0;
			int iRed = 0;
			int iGreen = 0;
			int iBlue = 0;
			int iRGBAvg = 0;
			// Gray of image processing.
			// The height of the image
   			for ( iY = 0; iY < bitmapClone.getHeight(); iY++ )
   			{
   				// The width of the image
   				for ( iX = 0; iX < bitmapClone.getWidth(); iX++ )
   				{
   					// To get pixel.
   					iPixel = mBitmap.getPixel(iX, iY);
   					// To get value of the red channel.
   					iRed = Color.red(iPixel);
   					// To get value of the green channel.
   					iGreen = Color.green(iPixel);
   					// To get value of the blue channel.
   					iBlue = Color.blue(iPixel);
   					// Compute value of gray.
   					iRGBAvg = ( iRed + iGreen + iBlue ) / 3;
   					// This is our threshold, you can change it.
   					if ( iRGBAvg > 120 )
   					{
   	   					// Set pixel to white.
   						bitmapClone.setPixel(iX, iY, Color.rgb(255, 255, 255));
   					}
   					else
   					{
   	   					// Set pixel to black.
   						bitmapClone.setPixel(iX, iY, Color.rgb(0, 0, 0));
   					}
   				}
   			}

   			// Set processed image to display.
   			ImgView.setImageBitmap(bitmapClone);
   			// Show the height of the image.
   			//String strInfo = "";
   			//strInfo = String.valueOf(mBitmap.getHeight());
   			//txtView.setText(strInfo);
			// Restart camera to preview.
			camera.startPreview();
			// To disable auto focus of callback function.
			camera.autoFocus(null);
   		}
   	 };

   	 // To establish Camera.AutoFocusCallback
   	 mAutoFocusCB = new AutoFocusCallback(){
    		@Override
    		public void onAutoFocus(boolean success, Camera camera){
    			// When auto focus is done and then we will take a picture.
    			if ( success == true )
    			{
					// Into take a picture of callback function.
					camera.takePicture(null, null, mPictureCB);
    			}
    		}
   	 };

   	 // While a user press the take a picture button, when it starts auto focus.
   	 btn_Capture.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				try{
					// To make sure the camera is open.
					if(mCamera != null){
						// Create a thread.
						new Thread(new Runnable() {
						    public void run() {
						    	// To execute the auto focus.
							    mCamera.autoFocus(mAutoFocusCB);
						    }
						  }).start();
					}
				}catch(Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {
		// TODO Auto-generated method stub
    	// Get parameters of the camera.
    	Camera.Parameters parameters = mCamera.getParameters();
		// Set size of the picture.
    	parameters.setPictureSize(640, 480);
    	// Set size of preview.
    	parameters.setPreviewSize(width, height);
    	// Set auto focus.
    	parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
    	// Set parameters of the camera.
		mCamera.setParameters(parameters);
		// Start preview.
		mCamera.startPreview();
	}

	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		// TODO Auto-generated method stub
    	// If the camera is initially successful and then to open camera.
    	if ( mCamera == null )
    	{
    		mCamera = Camera.open();
    	}
    	try {
    		// Set SurfaceHolder.
    		mCamera.setPreviewDisplay(holder);
    	}catch(Exception e) {
    		e.printStackTrace();
    	}
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		// TODO Auto-generated method stub
    	// Stop preview.
    	mCamera.stopPreview();
    	// Release Camera.
    	mCamera.release();
	}
}

HTML5 + Javascript

HTML5 + Javascript

<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
function imageLoaded(ev) {
    element = document.getElementById("cancan");
    c = element.getContext("2d");

	// The image, assumed to be 512x512
    im = ev.target;

    // Read the width and height of the canvas
    width = element.width;
    height = element.height;

    // Stamp the image on the left of the canvas.
    c.drawImage(im, 0, 0);

    // Get all canvas pixel data
    imageData = c.getImageData(0, 0, width, height);

	// The width index is output position.
    w2 = width / 2;

    // Run through the image.
	// The height of the image.
    for (y = 0; y < height; y++) {
		// *4 for 4 ints per pixel.
		// This is an input index.
        inpos = y * width * 4;
		// This is an output index.
        outpos = inpos + w2 * 4
		// The width of the image.
        for (x = 0; x < w2; x++) {
			// Get the pixel of the red channel.
            r = imageData.data[inpos++]
			// Get the pixel of the green channel.
            g = imageData.data[inpos++]
			// Get the pixel of the blue channel.
            b = imageData.data[inpos++]
			// Get the pixel of the alpha channel.
            a = imageData.data[inpos++]
            // Transform RGB color space to gray scale.
			gray =  (0.299 * r + 0.587 * g + 0.114 * b)
            // This is our threshold. You can change it.
            if ( gray > 120 )
			{
				// Set the pixel is white.
	            imageData.data[outpos++] = 255;
    	        imageData.data[outpos++] = 255;
        	    imageData.data[outpos++] = 255;
            	imageData.data[outpos++] = a;
			}
			else
			{
				// Set the pixel is black.
            	imageData.data[outpos++] = 0;
            	imageData.data[outpos++] = 0;
	            imageData.data[outpos++] = 0;
    	        imageData.data[outpos++] = a;
			}
        } // The closing "The width of the image".
    } // The closing "The height of the image".

    // Put pixel data on canvas.
    c.putImageData(imageData, 0, 0);
}

// Establish an image object.
im = new Image();
// Load the javascript function.
im.onload = imageLoaded;
// Code assumes this image is 512x512.
im.src = "B_01.jpg";
</script>
</head>

<body>
<!-- Create a canvas -->
<canvas id="cancan" width="1024", height="512">Canvas</canvas>
</body>
</html>

Matlab

Matlab

% Load image
x=imread('B_01.bmp');
% Transform RGB color space to gray scale
gray=rgb2gray(x);
% Binarization
BW=im2bw(x);
% Show the image
imshow(BW);

异常

Visual C++ 2010

  1. 请注意,如果您的位图文件位深度不是 24 位,您应该更改您的位图文件以适应此程序,或者您可以重写此源代码以适合您的位图格式。
  2. 您必须安装 Microsoft SDK v7.1,因为我包含了 windowscodes.lib#pragma comment(lib, "windowscodecs.lib")

C++ Builder XE5

  1. 您还应该取消选中“构建时使用运行时包”,在:项目 -> 选项 -> 包 -> 运行时包 -> 链接到运行时包 确保取消选中您正在使用的构建配置('release' / 'debug')下的三个项目(“链接到运行时包”、“链接到动态 RTL”和“链接到 Delphi 运行时库”)。

JAVA for NetBeans v8.0.2

  1. 这是另一种快速获取 RGB 值的方法。 它适用于大型图像。
private static int[][] convertTo2DWithoutUsingGetRGB(BufferedImage image) {

  final byte[] pixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
  final int width = image.getWidth();
  final int height = image.getHeight();
  final boolean hasAlphaChannel = image.getAlphaRaster() != null;
  int[][] result = new int[height][width];
  if (hasAlphaChannel) {
     final int pixelLength = 4;
     for (int pixel = 0, row = 0, col = 0; pixel < pixels.length; pixel += pixelLength) {
        int argb = 0;
        argb += (((int) pixels[pixel] & 0xff) << 24); // alpha
        argb += ((int) pixels[pixel + 1] & 0xff); // blue
        argb += (((int) pixels[pixel + 2] & 0xff) << 8); // green
        argb += (((int) pixels[pixel + 3] & 0xff) << 16); // red
        result[row][col] = argb;
        col++;
        if (col == width) {
           col = 0;
           row++;
        }
     }
  } else {
     final int pixelLength = 3;
     for (int pixel = 0, row = 0, col = 0; pixel < pixels.length; pixel += pixelLength) {
        int argb = 0;
        argb += -16777216; // 255 alpha
        argb += ((int) pixels[pixel] & 0xff); // blue
        argb += (((int) pixels[pixel + 1] & 0xff) << 8); // green
        argb += (((int) pixels[pixel + 2] & 0xff) << 16); // red
        result[row][col] = argb;
        col++;
        if (col == width) {
           col = 0;
           row++;
        }
     }
  }
  return result;
}
© . All rights reserved.