影象處理之積分圖應用四(基於區域性均值的影象二值化演算法)
阿新 • • 發佈:2018-11-11
影象處理之積分圖應用四(基於區域性均值的影象二值化演算法)
基本原理
均值法,選擇的閾值是區域性範圍內畫素的灰度均值(gray mean),該方法的一個變種是用常量C減去均值Mean,然後根據均值實現如下操作:
pixel = (pixel > (mean - c)) ? object : background
其中預設情況下引數C取值為0。object表示前景畫素,background表示背景畫素。
實現步驟
1. 彩色影象轉灰度影象
2. 獲取灰度影象的畫素資料,預計算積分圖
3. 根據輸入的引數視窗半徑大小從積分圖中獲取畫素總和,求得平均值
4.迴圈每個畫素,根據區域性均值實現中心畫素的二值化賦值
5.輸入二值影象
執行結果:
程式碼實現:
package com.gloomyfish.ii.demo;
import java.awt.image.BufferedImage;
public class FastMeanBinaryFilter extends AbstractImageOptionFilter {
private int constant;
private int radius;
public FastMeanBinaryFilter() {
constant = 10;
radius = 7; // 1,2,3,4,5,6,7,8
}
public int getConstant() {
return constant;
}
public void setConstant(int constant) {
this.constant = constant;
}
public int getRadius() {
return radius;
}
public void setRadius(int radius) {
this.radius = radius;
}
@Override
public BufferedImage process(BufferedImage image) {
int width = image.getWidth();
int height = image.getHeight();
BufferedImage dest = createCompatibleDestImage( image, null );
// 影象灰度化
int[] inPixels = new int[width*height];
int[] outPixels = new int[width*height];
byte[] binData = new byte[width*height];
getRGB( image, 0, 0, width, height, inPixels );
int index = 0;
for(int row=0; row<height; row++) {
int ta = 0, tr = 0, tg = 0, tb = 0;
for(int col=0; col<width; col++) {
index = row * width + col;
ta = (inPixels[index] >> 24) & 0xff;
tr = (inPixels[index] >> 16) & 0xff;
tg = (inPixels[index] >> 8) & 0xff;
tb = inPixels[index] & 0xff;
int gray= (int)(0.299 *tr + 0.587*tg + 0.114*tb);
binData[index] = (byte)gray;
}
}
// per-calculate integral image
IntIntegralImage grayii = new IntIntegralImage();
grayii.setImage(binData);
grayii.process(width, height);
int yr = radius;
int xr = radius;
int size = (yr * 2 + 1)*(xr * 2 + 1);
for (int row = 0; row < height; row++) {
for (int col = 0; col < width; col++) {
index = row * width + col;
// 計算均值
int sr = grayii.getBlockSum(col, row, (yr * 2 + 1), (xr * 2 + 1));
int mean = sr / size;
int pixel = binData[index]&0xff;
// 二值化
if(pixel > (mean-constant)) {
outPixels[row * width + col] = (0xff << 24) | (0xff << 16) | (0xff << 8) | 0xff;
} else {
outPixels[row * width + col] = (0xff << 24) | (0x00 << 16) | (0x00 << 8) | 0x00;
}
}
}
// 返回結果
setRGB(dest, 0, 0, width, height, outPixels);
return dest;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
2017年已經開始啦!部落格每個月都會有影象處理相關技術文章更新,歡迎大家繼續關注!