/**
* Copyright 2014 Comcast Cable Communications Management, LLC
*
* This file is part of CATS.
*
* CATS is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CATS is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CATS. If not, see <http://www.gnu.org/licenses/>.
*/
package com.comcast.cats.threshold;
import java.awt.Component;
import java.awt.image.BufferedImage;
/**
* This class implements otsu thresholding method to identify text from an
* image.
*
* @author aswathyjs
* @author rahulchandra
* @author maneshthomas
*/
public class RectangleIdentification extends Component
{
private static final String YELLOW = "yellow";
private static final String WHITE = "white";
private static final String BLACK = "black";
private static final long serialVersionUID = 1L;
private BufferedImage testImage;
private int check = 1; // to
// check
// all
// rectangles
// have
// been
// identified
private int index = 0;
private int coordinates[][] = new int[ 10000 ][ 4 ];
private String prevColour = WHITE;
/**
* Creates RectangleIdentification object.
*
* @param rgbImage
*/
public RectangleIdentification( BufferedImage rgbImage )
{
testImage = rgbImage;
}
/**
* Returns the coordinates.
*
* @param image
* : input image
* @param color
* : colour to be identified
* @return coordinates of the highlighted area
*/
public int[] getCoordinates( BufferedImage image, String color )
{
int pixel;
int[] xcoordinates = new int[ 10000 ];
int[] ycoordinates = new int[ 10000 ];
int[] coordinates1 = new int[ 4 ];
int red = 0;
int green = 0;
int blue = 0;
int arrayIndexofX = 0;
int columnNumber = 0;
int rowNumber = 0;
int checkRectangle = 0;
int minimumWidth = 40;
int minimumHeight = 10;
// Scan the image through x direction
for ( int j = 0; j < image.getHeight(); j++ )
{
checkRectangle = 0;
for ( int i = 0; i < image.getWidth(); i++ )
{
pixel = image.getRGB( i, j );
red = ( pixel >> 16 ) & 0xff;
green = ( pixel >> 8 ) & 0xff;
blue = ( pixel ) & 0xff;
if ( ( blue < red && blue < green && ( green - blue ) > 30 && color == YELLOW )
| ( ( Math.abs( blue - red ) < 20 && Math.abs( green - red ) < 20
&& Math.abs( blue - green ) < 20 && red > 200 && blue > 200 && green > 200 ) && color == WHITE )
| ( ( Math.abs( blue - red ) < 5 && Math.abs( green - red ) < 5 && red > 80
&& Math.abs( blue - green ) < 5 && blue > 80 && red < 150 && green > 80 && blue < 150 && green < 150 ) && color == BLACK ) )
{
checkRectangle = checkRectangle + 1;
columnNumber = i;
rowNumber = j;
}
}
int shift = 0;
if ( color == BLACK )
{
minimumWidth = 30;
shift = 10;
}
if ( color == YELLOW )
{
shift = 7;
}
if ( color == WHITE )
{
shift = 20;
}
if ( checkRectangle > minimumWidth )
{
if ( arrayIndexofX == 0 )
{
xcoordinates[ arrayIndexofX ] = rowNumber;
arrayIndexofX++;
}
else if ( arrayIndexofX != 0 )
{
if ( ( rowNumber - ( xcoordinates[ arrayIndexofX - 1 ] ) < shift ) )
{
xcoordinates[ arrayIndexofX ] = rowNumber;
arrayIndexofX++;
}
else
{
if ( arrayIndexofX < 15 )
{
xcoordinates[ arrayIndexofX - 1 ] = rowNumber;
arrayIndexofX = 0;
}
}
if ( ( arrayIndexofX - 1 ) == 0 )
{
xcoordinates[ 0 ] = rowNumber;
arrayIndexofX = 0;
}
}
}
}
int arrayIndexofY = 0;
int minimumshift = 20;
if ( arrayIndexofX == 0 )
{
arrayIndexofX = 1;
}
// scan the image through y direction
for ( int i = 0; i < image.getWidth(); i++ )
{
checkRectangle = 0;
for ( int j = xcoordinates[ 0 ]; j < xcoordinates[ arrayIndexofX - 1 ]; j++ )
{
pixel = image.getRGB( i, j );
red = ( pixel >> 16 ) & 0xff;
green = ( pixel >> 8 ) & 0xff;
blue = ( pixel ) & 0xff;
if ( ( blue < red && blue < green && ( green - blue ) > 30 && color == YELLOW )
| ( ( Math.abs( blue - red ) < 20 && Math.abs( green - red ) < 20
&& Math.abs( blue - green ) < 20 && red > 200 && blue > 200 && green > 200 ) && color == WHITE )
| ( ( Math.abs( blue - red ) < 5 && Math.abs( green - red ) < 5 && red > 80
&& Math.abs( blue - green ) < 5 && red < 160 && blue < 160 && green < 160 && blue > 80 && green > 80 ) && color == BLACK ) )
{
checkRectangle = checkRectangle + 1;
columnNumber = i;
rowNumber = j;
}
if ( color == BLACK )
{
minimumshift = 40;
}
if ( arrayIndexofY != 0 )
{
if ( ( columnNumber - ( ycoordinates[ arrayIndexofY - 1 ] ) > minimumshift ) )
{
break;
}
}
}
if ( color == BLACK )
{
minimumHeight = 10;
if ( rowNumber - xcoordinates[ 0 ] < 30 )
{
minimumHeight = 5;
}
}
if ( checkRectangle > minimumHeight )
{
ycoordinates[ arrayIndexofY ] = columnNumber;
arrayIndexofY++;
}
}
if ( arrayIndexofX != 0 && arrayIndexofY != 0 )
{
coordinates1[ 0 ] = xcoordinates[ 0 ]; // top left coordinates of
// the
// rectangle
coordinates1[ 1 ] = ycoordinates[ 0 ]; // top left coordinates of
// the
// rectangle
coordinates1[ 2 ] = xcoordinates[ arrayIndexofX - 1 ];// bottom
// right
// coordinates
// of the
// rectangle
coordinates1[ 3 ] = ycoordinates[ arrayIndexofY - 1 ];// bottom
// right
// coordinates
// of the
// rectangle
}
return coordinates1;
}
/**
* Sets the coordinates.
*
* @param image
* : input image
* @param color
* : colour of the highlighted region to be identified
* @return updated image
*/
public BufferedImage setCoordinates( BufferedImage image, String color )
{
coordinates[ index ] = getCoordinates( image, color );
if ( index != 0 )
{
if ( color == prevColour )
{
if ( Math.abs( coordinates[ index ][ 2 ] - coordinates[ index - 1 ][ 2 ] ) < 10
&& ( Math.abs( coordinates[ index ][ 0 ] - coordinates[ index - 1 ][ 0 ] ) > 10 ) )
{
coordinates[ index - 1 ][ 2 ] = coordinates[ index ][ 0 ];
}
else if ( Math.abs( coordinates[ index ][ 0 ] - coordinates[ index - 1 ][ 0 ] ) < 10
&& ( Math.abs( coordinates[ index ][ 2 ] - coordinates[ index - 1 ][ 2 ] ) > 10 ) )
{
coordinates[ index - 1 ][ 0 ] = coordinates[ index ][ 2 ] + 2;
}
else if ( ( Math.abs( coordinates[ index ][ 2 ] - coordinates[ index - 1 ][ 2 ] ) < 15 && ( Math
.abs( coordinates[ index ][ 0 ] - coordinates[ index - 1 ][ 0 ] ) < 15 ) ) )
{
coordinates[ index - 1 ][ 0 ] = coordinates[ index ][ 0 ] + 5;
}
}
prevColour = color;
}
int blackpixel = 0x00000000;
for ( int k = coordinates[ index ][ 1 ]; k < coordinates[ index ][ 3 ] + 1; k++ )
{
for ( int l = coordinates[ index ][ 0 ]; l < coordinates[ index ][ 2 ] + 1; l++ )
{
image.setRGB( k, l, blackpixel );
}
}
check = coordinates[ index ][ 1 ] + coordinates[ index ][ 3 ] + coordinates[ index ][ 0 ]
+ coordinates[ index ][ 2 ];
if ( check > 0 )
{
index++;
}
return image;
}
/**
* This function returns the coordinates of the highlighted rectangles.
*
* @return coordinates
*/
public int[] getRectangles()
{
int isrectanglefinished = 3;
String[] color = new String[ 3 ];
color[ 1 ] = YELLOW;
color[ 0 ] = WHITE;
color[ 2 ] = BLACK;
int colorIndex = 0;
while ( isrectanglefinished > 0 )
{
while ( check > 0 )
{
testImage = setCoordinates( testImage, color[ colorIndex ] );
if ( check == 0 )
{
colorIndex++;
isrectanglefinished--;
}
}
check = 1;
}
index--;
int[] coordinates1 = new int[ ( index + 1 ) * 4 ];
int i = 0;
int size = 0;
while ( index >= 0 )
{
int width = coordinates[ index ][ 3 ] - coordinates[ index ][ 1 ];
int height = coordinates[ index ][ 2 ] - coordinates[ index ][ 0 ];
if ( width > 40 && height > 15 )
{
coordinates1[ i ] = coordinates[ index ][ 1 ];
coordinates1[ i + 1 ] = coordinates[ index ][ 0 ];
coordinates1[ i + 2 ] = coordinates[ index ][ 3 ];
coordinates1[ i + 3 ] = coordinates[ index ][ 2 ];
i = i + 4;
size++;
}
index--;
}
// to remove the zero elements at the end
int[] rectangleCoordinates = new int[ size * 4 ];
for ( int j = 0; j < rectangleCoordinates.length; j++ )
{
rectangleCoordinates[ j ] = coordinates1[ j ];
}
return rectangleCoordinates;
}
}