package com.bdfus.piper.common.util.image;
import java.awt.Color;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
/**
* 已经二值化后的图片通过x,y投影实现切割,无粘连情况下效果很好
* @ClassName: CutImg
* @Description:TODO(这里用一句话描述这个类的作用)
* @author: chenyang
* @date: 2017年9月15日 下午5:02:25
*
*/
public class CutImg {
/**
* 图像向x轴做投影后的数组
*
* @param imagedata
* @param w
* @param h
* @return
*/
public static int[] xpro(BufferedImage input, int w, int h) {
int xpro[] = new int[w];
for (int j = 0; j < w; j++) {
for (int i = 0; i < h; i++) {
if (input.getRGB(j, i) !=-1)
xpro[j]++;
}
}
return xpro;
}
/**
* 基于x投影后再进行y轴投影
*
* @param imagedata
* @param w
* @param h
* @return
*/
public static int[] ypro(BufferedImage input, Rectangle xRectangle) {
int ypro[] = new int[(int) xRectangle.getHeight()];
int w = (int) xRectangle.getWidth();
int h = (int) xRectangle.getHeight();
for (int y = (int) xRectangle.getY(); y < h; y++) {
for (int x = (int) xRectangle.getX(); x < xRectangle.getX()+w; x++) {
if (input.getRGB(x, y) !=-1)
ypro[y]++;
}
}
return ypro;
}
public static BufferedImage verticalProjection(int[] xpro, BufferedImage input){
BufferedImage out = new BufferedImage(input.getWidth(), input.getHeight(), input.getType());
for (int i = 0; i < input.getHeight(); i++)
{
for (int j = 0; j < input.getWidth(); j++)
{
int color = new Color(255, 255, 255).getRGB(); //背景设置为白色。
out.setRGB(j, i, color);
}
}
/*将直方图的曲线设为黑色*/
for (int i = 0; i < input.getWidth(); i++)
{
for (int j = 0; j < xpro[i]; j++)
{
int color = new Color(0, 0, 0).getRGB(); //直方图设置为黑色
out.setRGB(i, j, color);
}
}
return out;
}
public static BufferedImage yVerticalProjection(int[] ypro, BufferedImage input){
BufferedImage out = new BufferedImage(input.getWidth(), input.getHeight(), input.getType());
for (int i = 0; i < input.getHeight(); i++)
{
for (int j = 0; j < input.getWidth(); j++)
{
int color = new Color(255, 255, 255).getRGB(); //背景设置为白色。
out.setRGB(j, i, color);
}
}
/*将直方图的曲线设为黑色*/
for (int y = 0; y < input.getHeight(); y++)
{
for (int x = 0; x < ypro[y]; x++)
{
int color = new Color(0, 0, 0).getRGB(); //直方图设置为黑色
out.setRGB(x, y, color);
}
}
return out;
}
/**
* 简单的基于投影的图像分割
* @param xpro
* @param w
* @param h
* @return
*/
public static Rectangle[] xproSegment(BufferedImage input, int[] xpro, int FZ) {
List<Rectangle> c = new ArrayList<Rectangle>();//用于储存分割出来的每个字符
int startIndex = 0;//记录进入字符区的索引
int endIndex = 0;//记录进入空白区域的索引
boolean inBlock = false;//是否遍历到了字符区内
// int totalWidth = 0;
for (int i = 0; i < input.getWidth(); ++i)
{
if (!inBlock && xpro[i] != 0)//进入字符区了
{
inBlock = true;
startIndex = i;
}
else if (xpro[i] == 0 && inBlock)//进入空白区了
{
endIndex = i;
inBlock = false;
int width = endIndex-startIndex;
if(width>=FZ){
Rectangle rectangle = new Rectangle(startIndex, 0, width, input.getHeight());
c.add(rectangle);
// totalWidth+=width;
}
}
}
//预处理一下,先将间隔很小的rectangle合并
List<Rectangle> cc = new ArrayList<Rectangle>();//用于储存分割出来的每个字符
for (int i = 1; i <c.size() ; i++){
Rectangle pre = c.get(i-1);
Rectangle now = c.get(i);
int xspace = (int) now.getX() - (int)(pre.getX()+pre.getWidth());
if(xspace<2 && (now.getWidth()<=FZ || pre.getWidth()<=4)){
//合并
int x = (int)(pre.getX());
int w = (int)(now.getX()-pre.getX()+now.getWidth());
Rectangle newR = new Rectangle(x, 0, w, input.getHeight());
cc.add(newR);
}else{
if(i==1){
cc.add(pre);
}
if(i!=c.size()-1){
Rectangle next = c.get(i+1);
int space = (int) next.getX() - (int)(now.getX()+now.getWidth());
if(space>=2 || (now.getWidth()>FZ && next.getWidth()>4)){
cc.add(now);
}
}else{
cc.add(now);
}
}
}
Rectangle result[] = cc.toArray(new Rectangle[]{});
//如果有三个,找出最多的再分割一次
if(result.length==3){
int maxIndex = 0;
int maxWidth = (int) result[0].getWidth();
for(int i=0;i<result.length;i++){
Rectangle r = result[i];
if(maxWidth<r.getWidth()){
maxWidth = (int) r.getWidth();
maxIndex = i;
}
}
Rectangle r = result[maxIndex];
int newXpro[] = new int[(int) r.getWidth()];
for(int i=0; i<r.getWidth(); i++){
newXpro[i] = xpro[(int) (i+r.getX())];
}
List<Bottom> bottoms = findXproBottom(newXpro,1);
if(bottoms!=null && bottoms.size()>0){
Bottom bottom = bottoms.get(0);
Rectangle finalResult[] = new Rectangle[4];
Rectangle new1 = new Rectangle((int)result[maxIndex].getX(), 0, bottom.getStartIndex()+1, input.getHeight());
Rectangle new2 = new Rectangle((int)result[maxIndex].getX()+bottom.getStartIndex(), 0, (int)r.getWidth()-bottom.getStartIndex()-1, input.getHeight());
for(int i=0; i<maxIndex; i++){
finalResult[i] = result[i];
}
finalResult[maxIndex] = new1;
finalResult[maxIndex+1] = new2;
for(int i=maxIndex+2; i<4; i++){
finalResult[i] = result[i-1];
}
return finalResult;
}
}
//多了一个,将最少那个和旁边的合并
if(result.length==5){
int minIndex = 0;
int minWidth = (int) result[0].getWidth();
for(int i=0;i<result.length;i++){
Rectangle r = result[i];
if(minWidth>r.getWidth()){
minWidth = (int) r.getWidth();
minIndex = i;
}
}
//第一个,直接和后面一个合并
if(minIndex==0){
Rectangle r1 = result[0];
Rectangle r2 = result[1];
int newWidth = (int) ((r2.getX()-r1.getX())+r2.getWidth());
Rectangle newr = new Rectangle((int)r1.getX(), 0, newWidth, (int)r1.getHeight());
Rectangle finalResult[] = new Rectangle[4];
finalResult[0] = newr;
fin
- 1
- 2
前往页