java将rgb彩色图片二值化处
OTSU算法,获取临界值,大于等于临界值的是白色,小于临界值的是黑色
public int getOptVal(int[][] arr,int w,int h){
int optimize=0
double fc=0
double[] p=new double[256]
int[] num=new int[256]
double total=w*h
for(int i=0
int count=0
for (int a = 0
for (int b = 0
int pixel=arr[a][b]
if(pixel==i){
count++
}
}
}
p[i]=count/total
num[i]=count
}
for(int i=0
double p0=0
double p1=0
double u0=0
double u1=0
int n0=0
int n1=0
for(int j=0
if(j<=i){
p0+=p[j]
u0=u0+j*p[j]
n0+=num[j]
}else{
p1+=p[j]
u1=u1+j*p[j]
n1+=num[j]
}
}
u0=u0*total/n0
u1=u1*total/n1
double fcTmp=p0*p1*((u0-u1)*(u0-u1))
if(fcTmp>fc){
fc=fcTmp
optimize=i
}
}
return optimize
}
生成黑白图片
public void getSplitRow(String src) throws IOException {
File file = new File(src)
BufferedImage bufferedImage = ImageIO.read(file)
int h = bufferedImage.getHeight()
int w = bufferedImage.getWidth()
int arr[][] = new int[w][h]
int[][] rowArr= new int[h][w]
// 获取图片每一像素点的灰度值
for (int i = 0
for (int j = 0
int rgb = bufferedImage.getRGB(i, j)
int gray=this.getImageRgb(rgb)
arr[i][j]=gray
rowArr[j][i]=gray
}
}
int optimize = this.getOTSU(arr, w, h)
BitSet[] binary=new BitSet[h]
for(int i=0
BitSet rowData=new BitSet(w)
for(int j=0
if(rowArr[i][j]>=optimize){
rowData.set(j)
}
}
binary[i]=rowData
}
int mostW=w
for(int i=0
for(int j=0
boolean flag=binary[i].get(j)
if(!flag){
if(j<mostW){
mostW=j
}
break
}
}
}
List<String> allBlank=new ArrayList<>()
int start=0
int end=0
for(int i=0
boolean flag=binary[i].get(mostW)
if(flag){
end++
}else{
if(end>0&&start>0){
allBlank.add(start+"@"+(start+end))
}
end=0
start=i
}
}
BufferedImage bufImg =
new BufferedImage(w, h, BufferedImage.TYPE_INT_BGR)
for (int i = 0
for (int j = 0
boolean flag= binary[j].get(i)
if(flag){
int white=new Color(255,255,255).getRGB()
bufImg.setRGB(i,j,white)
}else{
int black=new Color(0,0,0).getRGB()
bufImg.setRGB(i,j,black)
}
}
}
File newFile = new File("D:\zhanganhua\工作日志\2023-02-20\Desktop(1)\1001000.jpg")
ImageIO.write(bufImg, "png", newFile)
}
像素点的rgb转为一个灰度值
public int getImageRgb(int i) {
final int r = (i >> 16) & 0xff;
final int g = (i >> 8) & 0xff;
final int b = i & 0xff;
int result=(int)((r+g+b)/3);
return result;
}