首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

驗證碼圖片二值化處理:BitmapData 彩色雜訊問題分析與解決

     編輯:關於C語言

C# 驗證碼影像二值化:消除殘留彩色雜點的完整方案

使用 Bitmap.LockBits 直接操作像素資料進行灰度化與閾值二值化,但結果保留大量彩色雜點。問題在於灰度計算與閾值邏輯。

原始程式碼問題分析

var grays = Convert.ToInt16(srcRGBValues[i * scanWidth + k + 2]) +  // R
            Convert.ToInt16(srcRGBValues[i * scanWidth + k + 1]) +  // G
            Convert.ToInt16(srcRGBValues[i * scanWidth + k + 0]);   // B
if (grays >= 382) { /* 設為白 */ } else { /* 設為黑 */ }

三大缺陷:

  1. 灰度計算錯誤:單純加總 RGB (最大 765),閾值 382 約為 50% 亮度,但未加權 (人眼對綠最敏感)
  2. 未處理 Alpha 通道:Format24bppRgb 無 Alpha,但程式碼假設 3 bytes/pixel 正確
  3. 閾值過高/低導致雜訊保留:背景雜訊灰度可能接近閾值邊界

改進版二值化演算法

// 標準灰度公式:Y = 0.299R + 0.587G + 0.114B
int gray = (int)(0.299 * R + 0.587 * G + 0.114 * B);

// 自適應閾值 (Otsu 演算法) 或固定閾值 (如 128)
byte binary = (gray > 128) ? (byte)255 : (byte)0;
srcRGBValues[idx + 0] = srcRGBValues[idx + 1] = srcRGBValues[idx + 2] = binary;

完善的預處理流程

  1. 去噪:中值濾波或高斯模糊平滑雜點
  2. 灰度化:加權平均法
  3. 二值化:Otsu 自適應閾值或局部自適應閾值 (Sauvola/Niblack) 處理光照不均
  4. 形態學操作:開運算去除細小雜點,閉運算填補字符斷裂

關鍵程式碼修正點

  • 使用 PixelFormat.Format32bppArgb 統一 4 bytes/pixel,避免行跨越計算錯誤
  • 計算 scanWidth = bmpData.Stride 而非 Width * 3,Stride 含記憶體對齊填充
  • 雙重迴圈索引:idx = y * stride + x * 4
  • 處理完成後 UnlockBits 釋放鎖定

推薦開源庫

生產環境建議使用 OpenCvSharp 或 Emgu CV (OpenCV .NET 封裝),提供工業級影像處理管線:

using (var mat = BitmapConverter.ToMat(bitmap))
using (var gray = new Mat())
using (var binary = new Mat()) {
    Cv2.CvtColor(mat, gray, ColorConversionCodes.BGR2GRAY);
    Cv2.Threshold(gray, binary, 0, 255, ThresholdTypes.Otsu);
    // 形態學去噪
    Cv2.MorphologyEx(binary, binary, MorphTypes.Open, Cv2.GetStructuringElement(MorphShapes.Rect, new Size(2,2)));
    return BitmapConverter.ToBitmap(binary);
}

自行實作易遺漏邊界條件、效能優化,引用成熟庫更可靠。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved