Skip to main content

用10种程序语言做影像二值化(Image binarization)

用10种程序语言做影像二值化(Image binarization)

下载原始码:https://drive.google.com/open?id=0BzHb_OyLyVZlVHN1ZjVQVW9jR2c

简介
有些时候,我们需要将彩色影像转换为黑白影像,这很简单,利用门坎值的方法就可以做到。

作法


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);


下载原始码:https://drive.google.com/open?id=0BzHb_OyLyVZlVHN1ZjVQVW9jR2c

Popular posts from this blog

Python 日期與時間的處理

Visual Basic 6.0 (VB6) 程式語言案例學習 (10. 條碼列印程式)

寫作:波蘭文學習之旅:1-1. 波蘭文字母與發音(注音版)

Python 日期與時間的處理

Image

Visual Basic 6.0 (VB6) 程式語言案例學習 (10. 條碼列印程式)

Image

寫作:波蘭文學習之旅:1-1. 波蘭文字母與發音(注音版)

Image

數位影像處理:最佳化處理策略之快速消除扭曲演算法

Image

Visual Basic 6.0 (VB6) 程式語言案例學習 (04. 人事考勤管理系統)

Image

用10種程式語言做影像二值化(Image binarization)

Visual Basic 6.0 (VB6) 程式語言案例學習 (07. 收據列印程式)

Image

Visual Basic .Net (VB.Net) 程式語言案例學習 (03. 場地預約系統)

Image

Visual Basic 6.0 (VB6) 程式語言案例學習 (11. 生產線拍照程式)

Image

Visual Basic .Net (VB.Net) 程式語言案例學習 (06. 題庫測驗系統)

Image