用10種程式語言做影像二值化(Image binarization)
用10種程式語言做影像二值化(Image binarization)¶
簡介¶
有些時候,我們需要將彩色影像轉換為黑白影像,這很簡單,利用門檻值的方法就可以做到。
作法¶
Visual C++ 2010¶
// 影像的高度 for ( int iY = 0; iY < imageA->DibInfo->bmiHeader.biHeight; iY++ ) { // 影像的寬度 for ( int iX = 0; iX < imageA->DibInfo->bmiHeader.biWidth; iX++ ) { // 影像的索引值,因為這張影像的24 bit ,所以要乘以3 lIDXA = ( iX * 3 ) + ( iY * imageA->DibInfo->bmiHeader.biWidth * 3 ); // 取得藍色像素值 byteRGB_BA = imageA->DibArry[lIDXA+0]; // 取得綠色像素值 byteRGB_GA = imageA->DibArry[lIDXA+1]; // 取得紅色像素值 byteRGB_RA = imageA->DibArry[lIDXA+2]; // 將RGB利用YUV公式轉換Y(灰階) dobYUV_YA = (0.299 * byteRGB_RA + 0.587 * byteRGB_GA + 0.114 * byteRGB_BA); // 利用雙門檻值,灰階轉換黑白 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; } // 門檻值之外的填為黑色 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; } } // 影像的寬度 } // 影像的高度
C++ Builder XE5¶
//--------------------------------------------------------------------------- #include < vcl.h > #pragma hdrstop #include "Unit1.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; // 建立三個 TBitmap object 的指標 Graphics::TBitmap *TheBitmap, *TempBitmap, *OriginBitmap; // 宣告一個門檻值變數 int Threshold; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- void __fastcall TForm1::Exit1Click(TObject *Sender) { // 離開程式 Close(); } //--------------------------------------------------------------------------- void __fastcall TForm1::OpenFile1Click(TObject *Sender) { // 利用圖檔開啟對話框,開啟圖檔 if ( OpenPictureDialog1->Execute() ) { // 關閉自動調整大小 Image1->AutoSize=false; // 啟用伸展調整 Image1->Stretch=true; // 載入開啟的圖檔 Image1->Picture->LoadFromFile(OpenPictureDialog1->FileName); // 設定影像指標,指向開啟的圖檔 TheBitmap=Image1->Picture->Bitmap; // 建立一個 TBitmap object 保留原始影像 OriginBitmap = new Graphics::TBitmap(); // 保留原始影像 OriginBitmap->Assign(TheBitmap); // 設定 TImage object 保留原始影像 Image1->Picture->Bitmap->Assign(TheBitmap); // 如果檔案開啟成功,就設定一個旗標值 // 代表成功地開啟了一個檔案 OpenFile = 1; // 設定門檻值 Threshold = 100; // 設定水平滑動軸的位置為門檻值 ScrollBar1->Position = Threshold; } } //--------------------------------------------------------------------------- void __fastcall TForm1::ScrollBar1Change(TObject *Sender) { // 如果開啟檔案旗標為零,則退出副程式 if (OpenFile == 0) { return; } Byte *ptr, *tptr; // 由水平滑動軸獲得門檻值 Threshold = (int) ScrollBar1->Position; // 設定 TImage 回復為原始影像 Image1->Picture->Bitmap->Assign(OriginBitmap); // 建立暫存影像 TempBitmap = new Graphics::TBitmap(); // 暫存影像轉存至當下的影像 TempBitmap->Assign(TheBitmap); // 影像的高度 for (int y=0; y < TheBitmap->Height; y++) { // 設定水平掃描線的指標,指向 TheBitmap ptr = (Byte*) TheBitmap->ScanLine[y]; // 設定水平掃描線的指標,指向暫存 TempBitmap tptr = (Byte*) TempBitmap->ScanLine[y]; // 影像的寬度 for (int x=0; x < TheBitmap->Width; x++) { // 假如暫存影像像素大於門檻值,就分類為白色 if (tptr[x] > Threshold) { ptr[x] = (Byte) 255; } // 若暫存影像像素小於門檻值,就分類為黑色 else { ptr[x] = (Byte) 0; } } // 影像的寬度 } // 影像的高度 // 釋放暫存影像指標 delete TempBitmap; // 重繪視窗 Repaint(); // 設定二值化後的影像結果給 Image1 Image1->Picture->Bitmap->Assign(TheBitmap); } //---------------------------------------------------------------------------
Visual C# 2012¶
namespace Binarization_for_C_Sharp { public partial class Form1 : Form { // 宣告檔名字串 private string curFileName; // 宣告 bitmap object. private System.Drawing.Bitmap curBitmap; public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { // 建立一個檔案開啟對話框 OpenFileDialog openDlg = new OpenFileDialog(); // 設應檔案開啟對話框過濾副檔名的條件 openDlg.Filter = "All format | *.bmp; *.pcx; *.png; *.jpg; *.gif;" + "*.tif; *.ico; *.dxf; *.cgm; *.cdr; *.wmf; *.eps; *.emf"; // 設定檔案開啟對話框的標題 openDlg.Title = "Open a picture file."; // 如果檔案對話框開啟圖檔成功 if (openDlg.ShowDialog() == DialogResult.OK) { // 將檔名設定給檔名字串 curFileName = openDlg.FileName; try { // 經由檔名建立BMP影像物件 curBitmap = (Bitmap)Image.FromFile(curFileName); } // 如果獲得例外 catch (Exception exp) { // 跳出並顯示錯誤訊息 MessageBox.Show(exp.Message); } } // 重繪視窗 Invalidate(); } private void Form1_Paint(object sender, PaintEventArgs e) { // 從外部物件建立一個 graphics object Graphics g = e.Graphics; // 如果圖檔開啟成功 if (curBitmap != null) { // 將開啟的圖檔繪製到 Graphics 的物件中 g.DrawImage(curBitmap, 140, 10, curBitmap.Width, curBitmap.Height); } } private void button2_Click(object sender, EventArgs e) { // 如果圖檔開啟成功 if (curBitmap != null) { // 建立一個 color object. Color curColor; int ret; // 影像的寬度 for (int iX = 0; iX < curBitmap.Width; iX++) { // 影像的高度 for ( int iY = 0; iY < curBitmap.Height; iY++ ) { // 獲得RGB像素值 curColor = curBitmap.GetPixel(iX, iY); // 轉換RGB到YUV的Y(灰階) ret = (int) (curColor.R * 0.299 + curColor.G * 0.578 + curColor.B * 0.114); // 設定一個單門檻值,大於則為白色,小於則黑色 if (ret > 120) { ret = 255; } else { ret = 0; } // 寫入新的像素值 curBitmap.SetPixel( iX, iY, Color.FromArgb ( ret, ret ,ret ) ); } // 影像的寬度 } // 影像的高度 // 重繪視窗 Invalidate(); } } } }
Visual Basic .NET 2012¶
Public Class Form1 ' 建立一個檔名字串 Private curFileName As String ' 建立一個 bitmap object Private curBitmap As Bitmap Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click ' 建立一個開啟檔案對話框 Dim openFileDialog1 As New OpenFileDialog() ' 設定對話框初始目錄 openFileDialog1.InitialDirectory = ".\" ' 設定對話框過濾副檔名 openFileDialog1.Filter = "All format | *.bmp; *.pcx; *.png; *.jpg; *.gif;" + "*.tif; *.ico; *.dxf; *.cgm; *.cdr; *.wmf; *.eps; *.emf" ' 設定對話框過濾副檔名的索引值,預設是1 openFileDialog1.FilterIndex = 1 ' 設定對話框每次開啟的時候,都回到最後開啟檔案的目錄 ' 預設值是否(false) openFileDialog1.RestoreDirectory = True ' 如果檔案成功的開啟 If openFileDialog1.ShowDialog() = System.Windows.Forms.DialogResult.OK Then Try ' 設定對話框開啟的檔名給檔名字串 curFileName = openFileDialog1.FileName ' 確認檔名不是空白 If (curFileName IsNot Nothing) Then ' 經由檔名建立一個BMP物件,名為b Dim b As Bitmap = New Bitmap(curFileName) ' 經由b建立一個大小及色彩空間相同的BMP物件 curBitmap = New Bitmap(b.Width, b.Height, System.Drawing.Imaging.PixelFormat.Format32bppPArgb) ' 將b複製到BMP物件 curBitmap = b.Clone() End If ' 如果出現例外,就顯示錯誤訊息 Catch Ex As Exception MessageBox.Show("Cannot read file from disk. Original error: " & Ex.Message) Finally End Try ' 重繪視窗 Invalidate() End If End Sub Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles MyBase.Paint ' 如果圖檔成功開啟 If (curBitmap IsNot Nothing) Then ' 將BMP繪製在Graphics物件中 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 ' 影像的高度 For y As Integer = 0 To curBitmap.Height - 1 ' 影像的寬度 For x = 0 To curBitmap.Width - 1 ' 獲得RGB像素值 Dim curPixColor As Color = curBitmap.GetPixel(x, y) ' 宣告灰階像素值變數 Dim ret As Integer ' 轉換RGB到YUV的Y(灰階) ret = (curPixColor.R * 0.299 + curPixColor.G * 0.578 + curPixColor.B * 0.114) ' 像素值若大於門檻值,則為白色,反之,黑色 If ret > 120 Then curBitmap.SetPixel(x, y, Color.White) Else curBitmap.SetPixel(x, y, Color.Black) End If ' 影像的寬度 Next ' 影像的高度 Next ' 重繪視窗 Invalidate() End Sub End Class
Visual Basic 6.0¶
' 當表單載入時的副程式 Private Sub Form_Load() ' 經由檔名載入影像 Picture1.Picture = LoadPicture(App.Path & "\B_01.bmp") ' 宣告X軸變數 Dim lngX As Long ' 宣告Y軸變數 Dim lngY As Long ' 宣告灰階變數 Dim intS ' 分別宣告RGB變數 Dim intR, intG, intB ' Set up the scale mode is pixel. Picture1.ScaleMode = 3 ' 設定圖形框自動重繪 Picture1.AutoRedraw = True ' 設定圖形框的單位為像素 Picture2.ScaleMode = 3 ' 設定圖形框自動重繪 Picture2.AutoRedraw = True ' 影像的高度 For lngY = 0 To Picture1.ScaleHeight ' 影像的寬度 For lngX = 0 To Picture1.ScaleWidth ' 取得紅色像素值 intR = (Picture1.Point(lngX, lngY) And &HFF) ' 取得綠色像素值 intG = (Picture1.Point(lngX, lngY) And &HFF00&) \ 256 ' 取得藍色像素值 intB = (Picture1.Point(lngX, lngY) And &HFF0000) \ 65536 ' RGB轉換為灰階值 intS = (intR + intG + intB) / 3 ' 灰階值大於門檻值,則為白色 If intS > 120 Then intS = 255 ' 反之,則為黑色 Else intS = 0 End If ' 將黑白像素值寫入圖形框 Picture2.PSet (lngX, lngY), RGB(intS, intS, intS) ' 影像的寬度 Next lngX ' 影像的高度 Next lngY End Sub
JAVA with NetBeans v8.1¶
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); // 設定檔案開啟對話框的初始目錄 f.setDirectory("."); // 顯示檔案對話框,並等待使用者操作 f.show(); // 紀錄檔案目錄字串 String directory = f.getDirectory(); // 建立檔案路徑及名稱的字串 String filepath = directory+f.getFile(); // 宣告 BufferedImage 物件 BufferedImage img = null; try { // 經由檔案路徑及名稱讀取圖檔 img = ImageIO.read(new File(filepath)); // 準備二值化 int[][] result = convertToBinarization(img); // 顯示二值化影像 jLabel1.setIcon(new javax.swing.ImageIcon(img)); } // 如果出現例外,則顯示錯誤訊息 catch (IOException e) { System.err.println("I could not load the file \'"+directory+"'. Sorry."); } } // RGB影像二值化的函式 private static int[][] convertToBinarization(BufferedImage image) { // 獲得影像的寬度 int width = image.getWidth(); // 獲得影像的高度 int height = image.getHeight(); // 建立二維陣列紀錄影像像素資料 int[][] result = new int[height][width]; // 影像的高度 for (int row = 0; row < height; row++) { // 影像的寬度 for (int col = 0; col < width; col++) { // 獲得RGB值 result[row][col] = image.getRGB(row, col); // 獲得整數的RGB值 int iRet = result[row][col]; // 宣告透明度(alpha)變數 int iA = 0; // 宣告紅色變數 int iR = 0; // 宣告綠色變數 int iG = 0; // 宣告藍色變數 int iB = 0; int iGray = 0; // 獲得透明度值 iA = (((int) iRet & 0xff) << 24); // 獲得藍色值 iB = ((int) iRet & 0xff); // 獲得綠色值 iG = (((int) iRet & 0x00ff00) >> 8); // 獲得紅色值 iR = (((int) iRet & 0xff0000) >> 16); // RGB轉換為灰階 iG = ( iR + iG + iB ) / 3; // 灰階值大於門檻值 if ( iG > 120 ) { // 設定為白色 iRet = 0xffffff; // 寫入白色值到影像中 image.setRGB(row, col, iRet); } else { // 寫入黑色值到影像中 image.setRGB(row, col, 0); } } } // 回傳處理結果值 return result; }
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; // 宣告檔名字串 Str : String; implementation {$R *.dfm} procedure TForm1.Button2Click(Sender: TObject); var PByte :PByteArray; Gray,x,y :Integer; ImageBmp :TBitmap; begin // 如果檔名字串為空白,則顯示錯誤訊息 if Str = '' then showmessage('Can not open this file, because it is an empty.') // 反之,有檔名則繼續處理 else begin // 建立一個TBitmap object. ImageBmp :=TBitmap.Create; // 儲存開啟的圖檔資料 ImageBmp.Assign(Image1.Picture.Bitmap); // 設定影像格式為 24 bits ImageBmp.PixelFormat :=pf24Bit; // 影像的高度 for y:=0 to ImageBmp.Height-1 do begin // 設定Y軸掃描線 PByte := ImageBmp.scanline[y]; // 影像的寬度 for x:=0 to ImageBmp.Width-1 do begin // 四捨五入轉換RGB為YUV的Y(灰階) Gray:=Round(PByte[x*3+2]*0.3+PByte[x*3+1]*0.59+PByte[x*3]*0.11); // 當灰階值大於門檻值 if Gray > 120 then // 設定為白色 begin PByte[x*3]:=255; PByte[x*3+1]:=255; PByte[x*3+2]:=255; end // 反之,則為黑色 else begin PByte[x*3]:=0; PByte[x*3+1]:=0; PByte[x*3+2]:=0; end end; end; // 影像框儲存處理後的影像 Image1.Picture.Bitmap.Assign(ImageBmp); // 釋放 TBitmap object 的記憶體 ImageBmp.Free; end; end; procedure TForm1.Button1Click(Sender: TObject); var // 宣告完整路徑的字串 Path:string; begin // 記錄路徑為應用程式的路徑 path:=ExtractFilePath(application.ExeName); // 設定圖形開啟對話框的初始路徑 OpenPictureDialog1.InitialDir := Path; // 顯示圖形開啟對話框 if OpenPictureDialog1.Execute then begin // 記錄圖形開啟對話框的檔案名稱 Str := OpenPictureDialog1.FileName; // 藉由檔案名稱載入圖檔 Image1.Picture.LoadFromFile(Str); end; end; end.
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); // 設定視窗的像素格式為允許透明值(alpha) // 設定這個數值會覆寫掉原來系統預設值 getWindow().setFormat(PixelFormat.TRANSLUCENT); // 設定視窗特徵為沒有標題 requestWindowFeature(Window.FEATURE_NO_TITLE); // 設定視窗版型為全螢幕 getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); // 藉由資源類別(R)設定視窗的版型 setContentView(R.layout.activity_main); // 設定視窗的方向 this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); // 設定元件 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); // 宣告並獲得 SurfaceHolder,這允許控制或改變像素 SurfaceHolder mSurfaceHolder = mSurfaceView.getHolder(); mSurfaceHolder.addCallback(this); mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); // 建立拍照的回呼函式 mPictureCB = new PictureCallback(){ // 開始二值化 // 覆寫 onPictureTaken 函式. @Override public void onPictureTaken(byte[] data, Camera camera){ // BitmapFactory 可以解碼RAW資料為BMP格式 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; // 灰階影像處理轉黑白影像 // 影像的高度 for ( iY = 0; iY < bitmapClone.getHeight(); iY++ ) { // 影像的寬度 for ( iX = 0; iX < bitmapClone.getWidth(); iX++ ) { // 獲得像素值 iPixel = mBitmap.getPixel(iX, iY); // 獲得紅色像素 iRed = Color.red(iPixel); // 獲得綠色像素 iGreen = Color.green(iPixel); // 獲得藍色像素 iBlue = Color.blue(iPixel); // 計算灰階值 iRGBAvg = ( iRed + iGreen + iBlue ) / 3; // 當灰階值大於門檻值 if ( iRGBAvg > 120 ) { // 設定像素為白色 bitmapClone.setPixel(iX, iY, Color.rgb(255, 255, 255)); } else { // 設定像素為黑色 bitmapClone.setPixel(iX, iY, Color.rgb(0, 0, 0)); } } } // 設定顯示處理過的影像 ImgView.setImageBitmap(bitmapClone); // 攝影機啟動預覽 camera.startPreview(); // 關閉自動對焦回呼函式 camera.autoFocus(null); } }; // 建立自動對焦回呼函式 mAutoFocusCB = new AutoFocusCallback(){ @Override public void onAutoFocus(boolean success, Camera camera){ // 當對焦成功時,才執行拍照功能 if ( success == true ) { // 進入拍照回呼函式 camera.takePicture(null, null, mPictureCB); } } }; // 當使用者按下拍照鈕,開啟自動對焦回呼函式 btn_Capture.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { try{ // 確認攝影機有開啟 if(mCamera != null){ // 建立一個執行緒 new Thread(new Runnable() { public void run() { // 執行自動對焦 mCamera.autoFocus(mAutoFocusCB); } }).start(); } }catch(Exception e) { e.printStackTrace(); } } }); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); return true; } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { // 獲得相機參數 Camera.Parameters parameters = mCamera.getParameters(); // 設定影像大小 parameters.setPictureSize(640, 480); // 設定預覽大小 parameters.setPreviewSize(width, height); // 設定自動對焦 parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO); // 將參數寫入相機 mCamera.setParameters(parameters); // 開始預覽 mCamera.startPreview(); } @Override public void surfaceCreated(SurfaceHolder holder) { // 如果相機初始化成功就開啟相機 if ( mCamera == null ) { mCamera = Camera.open(); } try { // 設定 SurfaceHolder. mCamera.setPreviewDisplay(holder); }catch(Exception e) { e.printStackTrace(); } } @Override public void surfaceDestroyed(SurfaceHolder holder) { // TODO Auto-generated method stub // 停止預覽 mCamera.stopPreview(); // 釋放相機 mCamera.release(); } }
HTML5 + Javascript¶
<!DOCTYPE html> <html> <head> <script type="text/javascript"> function imageLoaded(ev) { element = document.getElementById("cancan"); c = element.getContext("2d"); // 這張影像解析度為 512x512 im = ev.target; // 讀取影像元素的寬與高 width = element.width; height = element.height; // 設定左邊 canvas 的位置 c.drawImage(im, 0, 0); // 獲得左邊 canvas 的像素資料 imageData = c.getImageData(0, 0, width, height); // 右邊 canvas 的X軸起始位置 w2 = width / 2; // 開始二值化 // 影像的高度 for (y = 0; y < height; y++) { // 每一個像素值為 32 bits // 設定Y軸索引值 inpos = y * width * 4; // 設定輸出索引值 outpos = inpos + w2 * 4 // 影像的寬度 for (x = 0; x < w2; x++) { // 取得紅色像素 r = imageData.data[inpos++] // 取得綠色像素 g = imageData.data[inpos++] // 取得藍色像素 b = imageData.data[inpos++] // 取得透明值 a = imageData.data[inpos++] // RGB轉換YUV的Y(灰階) gray = (0.299 * r + 0.587 * g + 0.114 * b) // 若灰階值大於門檻值 if ( gray > 120 ) { // 設定輸出像素為白色 imageData.data[outpos++] = 255; imageData.data[outpos++] = 255; imageData.data[outpos++] = 255; imageData.data[outpos++] = a; } else { // 設定輸出像素為黑色 imageData.data[outpos++] = 0; imageData.data[outpos++] = 0; imageData.data[outpos++] = 0; imageData.data[outpos++] = a; } } // 影像的寬度 } // 影像的高度 // 將影像資料繪製在 canvas. c.putImageData(imageData, 0, 0); } // 建立影像物件. im = new Image(); // 設定JavaScript的函式 im.onload = imageLoaded; // 這張影像的解析度是 512x512. im.src = "B_01.jpg"; </script> </head> <body> <!—建立一個 canvas --> <canvas id="cancan" width="1024", height="512">Canvas</canvas> </body> </html>
Matlab 2011¶
% 載入影像 x=imread('B_01.bmp'); % RGB轉換為灰階 gray=rgb2gray(x); % 二值化 BW=im2bw(x); % 顯示影像 imshow(BW);