package com.imt.intimamedia.helpers { import com.imt.intimamedia.vo.ScaleCjVo; import flash.display.BitmapData; import flash.geom.Point; public class ScaleDetection { public function ScaleDetection() { } /** * Contantes */ public static const MINIMUM_DISTANCE : int = 10; public static const TOLERANCE : int = 2; public static const TELEMED : String = "TELEMED"; public static const YELLOW : String = "YELLOW"; public static const GREEN : String = "GREEN"; public static const BLUE : String = "BLUE"; public static const BLUE_GREY : String = "BLUE_GREY"; public static const BLUE_GREEN : String = "BLUE_GREEN"; public static const ORANGE : String = "ORANGE"; public static const ORANGE_GREY : String = "ORANGE_GREY"; public function searchTicks( column : int, rowStart : int, rowEnd : int, bitmapData : BitmapData, redStart : uint, greenStart : uint, blueStart : uint, redEnd : uint, greenEnd : uint, blueEnd : uint, type : String, colorScale : String ) : Object { var color : uint = 0; var red : uint = 0; var green : uint = 0; var blue : uint = 0; var list : Array = new Array(); var scaleVo : ScaleCjVo = new ScaleCjVo(); scaleVo.type = type; scaleVo.color = colorScale; /** * Boucle qui parcourt les pixels + 2 de la ligne détéctée */ for( var ordinate : uint = rowStart; ordinate < rowEnd+1; ordinate++ ) { color = bitmapData.getPixel( column + 1, ordinate ); red = color >> 16 & 0xFF; green = color >> 8 & 0xFF; blue = color & 0xFF; if( ordinate == 136 || ordinate == 229 || ordinate == 323 || ordinate == 417 || ordinate == 510 || ordinate == 604 || ordinate == 698 || ordinate == 791) trace("Test des paliers"); if( ( red >= redStart && red <= redEnd ) && ( green >= greenStart && green <= greenEnd ) && ( blue >= blueStart && blue <= blueEnd ) ) { list.push( ordinate ); } } var distanceBetweenPoints : uint = list[ 1 ] - list[ 0 ]; scaleVo.segment = distanceBetweenPoints; scaleVo.points = new Array(); scaleVo.points.push( new Point( column, list[ 0 ] ) ); scaleVo.points.push( new Point( column, list[ 1 ] ) ); scaleVo.number = 2; for( var value : uint = 2; value < list.length; value++ ) { if( list[ value ] - list[ value - 1 ] < distanceBetweenPoints + 2 && list[ value ] - list[ value - 1 ] > distanceBetweenPoints - 2 ) { scaleVo.points.push( new Point( column, list[ value ] ) ); scaleVo.number++; } } scaleVo.start = scaleVo.points[ 0 ]; scaleVo.end = scaleVo.points[ scaleVo.points.length - 1 ]; scaleVo.distance = scaleVo.end.y - scaleVo.start.y; return scaleVo; } /** * Recherche d'une échelle Telemed */ private function searchTelemed() : ScaleCjVo { var scaleVo : ScaleCjVo = new ScaleCjVo(); return scaleVo; } /** * Recherche d'une échelle Telemed de Christophe */ private function searchTelemedLive() : ScaleCjVo { var scaleVo : ScaleCjVo = new ScaleCjVo(); return scaleVo; } /** * Recherche d'une échelle Terason */ private function searchTerason( bitmapData : BitmapData ) : ScaleCjVo { var terasonDetected : Boolean = false; var terasonArray : Array = new Array(); var scaleVo : ScaleCjVo = new ScaleCjVo(); /** * Parcours de l'image à la recherche de couleurs spécifiques (Terrason, Telemed...) * * Boucle qui parcours les colonnes de l'image de la droite vers la gauche */ for( var index : int = bitmapData.width ; index > 0; index-- ) { /** * Boucle qui parcours les pixels pour chaque colonne du haut vers le bas de l'image */ for( var ordinate : int = 0; ordinate < bitmapData.height; ordinate++ ) { var color : uint = bitmapData.getPixel( index, ordinate ); var red : uint = color >> 16 & 0xFF; var green : uint = color >> 8 & 0xFF; var blue : uint = color & 0xFF; /** * Détection d'un Terrasson */ if( ( blue >= 246 && blue <= 255 ) && ( red >= 0 && red <= 4 ) && ( green >= 253 && green <= 255 ) ) { var pointToAdd : Point = new Point(); pointToAdd.x = index; pointToAdd.y = ordinate; terasonDetected = true; terasonArray.push( pointToAdd ); } } } /** * Détection d'un Terrasson et recherche de l'échelle associée */ if( terasonDetected ) { var temporaryPoint : Point = null; var distanceCounter : int = 0; var totalDistances : Array = new Array(); var tickCounter : int = 0; var arrayOfPoints : Array = new Array(); var bestArray : Array = new Array(); /** * Recherche du nombre de points par colonne */ for( var terasonPointIndex : int = 0; terasonPointIndex < terasonArray.length; terasonPointIndex++ ) { if( terasonPointIndex > 0 && terasonArray[ terasonPointIndex ].x != terasonArray[ terasonPointIndex - 1 ].x ) { var obj : Object = new Object(); obj.column = terasonArray[ terasonPointIndex - 1 ].x; obj.number = tickCounter; arrayOfPoints.push( obj ) tickCounter = 1; } else { tickCounter++; } } var maxObject : Object = null; /** * Recherche de la colonne ayant le plus de points */ for each( var object : Object in arrayOfPoints ) { if( maxObject == null ) { maxObject = object } else { if( object.number > maxObject.number ) maxObject = object; } } /** * Création du tableau de points pour cette colonne */ for each( var point : Point in terasonArray ) { if( point.x == maxObject.column ) { bestArray.push( point ); } } /** * Création de l'objet de retour à partir de la meilleure colonne */ scaleVo.color = "BLUE"; scaleVo.type = "TERASON"; scaleVo.points = bestArray; scaleVo.number = bestArray.length; scaleVo.segment = bestArray[ 1 ].y - bestArray[ 0 ].y; scaleVo.start = new Point( bestArray[ 0 ].x, bestArray[ 0 ].y ); scaleVo.end = new Point( bestArray[ bestArray.length - 1 ].x, bestArray[ bestArray.length - 1 ].y ); scaleVo.distance = scaleVo.end.y - scaleVo.start.y; /** * Détermination de la régularité des segments */ var minimum : int = ( bestArray[ 1 ].y - bestArray[ 0 ].y ) - 15; var maximum : int = ( bestArray[ 1 ].y - bestArray[ 0 ].y ) + 15; var counterOfRegularity : int = 0; for( var indexReg : int = 0; indexReg < bestArray.length; indexReg++ ) { if( indexReg > 0 ) { if( bestArray[ 1 ].y - bestArray[ 0 ].y < maximum && bestArray[ 1 ].y - bestArray[ 0 ].y > minimum ) { counterOfRegularity++; } } } scaleVo.regularity = ( counterOfRegularity / ( bestArray.length - 1 ) ) * 100; /** * Détermination de la taille de l'échelle */ scaleVo.ratio = ( scaleVo.distance / bitmapData.height ) * 100; } return scaleVo; } /** * Recherche d'une échelle en nuance de gris */ private function searchGreyScale() : ScaleCjVo { var scaleVo : ScaleCjVo = new ScaleCjVo(); return scaleVo; } public function findScale( bitmapData : BitmapData ) : Object { var index : int = bitmapData.width; var ordinate : int = 0; var color : uint = 0; var red : uint = 0; var green : uint = 0; var blue : uint = 0; var grey : uint = 0; var terasonDetected : Boolean = false; var telemedDetected : Boolean = false; var telemedLiveDetected : Boolean = false; var greyScaleDetected : Boolean = false; var terasonArray : Array = new Array(); var telemedYellowArray : Array = new Array(); var greyScaleArray : Array = new Array(); var startY : int = 0; var endY : int = 0; var distanceCounter : int = 0; var tickCounter : int = 0; var distanceFirstSegment : int = 0; var distanceSecondSegment : int = 0; var totalDistances : Array = new Array(); var minimum : int = 0; var maximum : int = 0; var distance : int = 0; var start : Point = null; var end : Point = null; var scaleVo : ScaleCjVo = null; var temporaryPoint : Point = null; scaleVo = searchTerason( bitmapData ); if( scaleVo.type == "TERASON" ) return scaleVo; /** * Parcours de l'image à la recherche de couleurs spécifiques (Terrason, Telemed...) * * Boucle qui parcours les colonnes de l'image de la droite vers la gauche */ for( index; index > 0; index-- ) { /** * Boucle qui parcours les pixels pour chaque colonne du haut vers le bas de l'image */ for( ordinate = 0; ordinate < bitmapData.height; ordinate++ ) { color = bitmapData.getPixel( index, ordinate ); red = color >> 16 & 0xFF; green = color >> 8 & 0xFF; blue = color & 0xFF; /** * Détection du jaune du Telemed de Christophe */ if( ( blue >= 0 && blue <= 25 ) && ( red >= 240 && red <= 255 ) && ( green >= 240 && green <= 255 ) ) { point = new Point(); point.x = index; point.y = ordinate; telemedLiveDetected = true; telemedYellowArray.push( point ); } } } if( telemedLiveDetected ) { for each( var telemedPoint : Point in telemedYellowArray ) { if( temporaryPoint != null ) { minimum = ( telemedPoint.y - temporaryPoint.y ) - 15; maximum = ( telemedPoint.y - temporaryPoint.y ) + 15; if( distanceCounter < maximum && distanceCounter > minimum ) { tickCounter++; totalDistances.push( distanceCounter ); if( tickCounter == 3 ) { var listYellow : Array = new Array(); var lastPointYellow : Point; for each( var point : Point in telemedYellowArray ) { if( telemedYellowArray[ 0 ].x == point.x ) { listYellow.push( point ); lastPointYellow = point; } } start = new Point( telemedYellowArray[ 0 ].x, telemedYellowArray[ 0 ].y ); end = new Point( lastPointYellow.x, lastPointYellow.y ); distance = end.y - start.y; scaleVo = new ScaleCjVo(); scaleVo.color = YELLOW; scaleVo.type = TELEMED; scaleVo.points = listYellow; scaleVo.number = listYellow.length; scaleVo.segment = telemedYellowArray[ 1 ].y - telemedYellowArray[ 0 ].y; scaleVo.distance = distance; scaleVo.start = start; scaleVo.end = end; return scaleVo; } } else { tickCounter = 0; totalDistances = new Array(); } distanceCounter = Math.abs( telemedPoint.y - temporaryPoint.y ); } temporaryPoint = telemedPoint; } } /** * Parcours de l'image à la recherche de couleurs spécifiques (Telemed) * * Boucle qui parcours les colonnes de l'image de la droite vers la gauche */ for( index = bitmapData.width; index > 0; index-- ) { var numberOfPixels : int = 0; var firstPoint : int = -1; var colorScale : String; var redStart : uint; var greenStart : uint; var blueStart : uint; var redEnd : uint; var greenEnd : uint; var blueEnd : uint; var temp : int = 0; var lastPoint : Boolean = false; /** * Boucle qui parcours les pixels pour chaque colonne du haut vers le bas de l'image */ for( ordinate = 0; ordinate < bitmapData.height; ordinate++ ) { color = bitmapData.getPixel( index, ordinate ); red = color >> 16 & 0xFF; green = color >> 8 & 0xFF; blue = color & 0xFF; lastPoint = false; if( index == 73 ) trace("Affichage de la barre"); /** * Détection de la couleur de l'échelle d'un TELEMED (vert) */ if( ( red >= 140 && red <= 185 ) && ( green >= 200 && green <= 235 ) && ( blue >= 135 && blue <= 185 ) ) { if( firstPoint == -1 ) firstPoint = ordinate; numberOfPixels++; if( colorScale != GREEN ) numberOfPixels = 1; redStart = 140; greenStart = 200; blueStart = 135; redEnd = 185; greenEnd = 235; blueEnd = 185; colorScale = GREEN; temp = 0; lastPoint = true; } /** * Détection de la couleur de l'échelle d'un TELEMED (bleue) */ if( ( red >= 95 && red <= 115 ) && ( green >= 105 && green <= 125 ) && ( blue >= 140 && blue <= 190 ) ) { if( firstPoint == -1 ) firstPoint = ordinate; numberOfPixels++; if( colorScale != BLUE ) numberOfPixels = 1; redStart = 100; greenStart = 110; blueStart = 140; redEnd = 115; greenEnd = 125; blueEnd = 185; colorScale = BLUE; temp = 0; lastPoint = true; } /** * Détection de la couleur de l'échelle d'un TELEMED (bleue sur fond gris clair) */ if( ( red >= 115 && red <= 135 ) && ( green >= 130 && green <= 150 ) && ( blue >= 140 && blue <= 165 ) ) { if( firstPoint == -1 ) firstPoint = ordinate; numberOfPixels++; if( colorScale != BLUE_GREY ) numberOfPixels = 1; redStart = 115; greenStart = 130; blueStart = 140; redEnd = 135; greenEnd = 150; blueEnd = 165; colorScale = BLUE_GREY; temp = 0; lastPoint = true; } /** * Détection de la couleur de l'échelle d'un TELEMED (bleue verte) */ if( ( red >= 75 && red <= 130 ) && ( green >= 100 && green <= 130 ) && ( blue >= 40 && blue <= 100 ) ) { if( firstPoint == -1 ) firstPoint = ordinate; numberOfPixels++; if( colorScale != BLUE_GREEN ) numberOfPixels = 1; redStart = 75; greenStart = 100; blueStart = 40; redEnd = 130; greenEnd = 130; blueEnd = 100; colorScale = BLUE_GREEN; temp = 0; lastPoint = true; } /** * Détection de la couleur de l'échelle d'un TELEMED (orange) */ if( ( red >= 145 && red <= 175 ) && ( green >= 110 && green <= 130 ) && ( blue >= 75 && blue <= 105 ) ) { if( firstPoint == -1 ) firstPoint = ordinate; numberOfPixels++; if( colorScale != ORANGE ) numberOfPixels = 1; redStart = 140; greenStart = 105; blueStart = 70; redEnd = 180; greenEnd = 135; blueEnd = 120; colorScale = ORANGE; temp = 0; lastPoint = true; } /** * Détection de la couleur de l'échelle d'un TELEMED (orange sur fond gris clair) */ if( ( red >= 150 && red <= 195 ) && ( green >= 150 && green <= 170 ) && ( blue >= 90 && blue <= 160 ) ) { if( firstPoint == -1 ) firstPoint = ordinate; numberOfPixels++; if( colorScale != ORANGE_GREY ) numberOfPixels = 1; redStart = 150; greenStart = 150; blueStart = 90; redEnd = 195; greenEnd = 170; blueEnd = 160; colorScale = ORANGE_GREY; temp = 0; lastPoint = true; } /** * Verification de la présence d'une échelle après 2 pixels différents */ if( !lastPoint ) { if( temp >= 1 ) { if( numberOfPixels > bitmapData.height * .75 && numberOfPixels < 40 ) { return searchTicks( index, firstPoint, ordinate, bitmapData, redStart, greenStart, blueStart, redEnd, greenEnd, blueEnd, TELEMED, colorScale ); } firstPoint = -1; numberOfPixels = 0; } temp++; } /** * Verification de la présence d'une échelle en fin d'image (Les TELEMED on un seul pixel de fin) */ if( ordinate == bitmapData.height - 1 ) { if( numberOfPixels > bitmapData.height * .75 ) { return searchTicks( index, firstPoint, ordinate, bitmapData, redStart, greenStart, blueStart, redEnd, greenEnd, blueEnd, TELEMED, colorScale ); } } } } /** * Boucle qui parcours les colonnes de la droite vers la gauche sur 100% de l'image */ for( index = bitmapData.width; index > 0; index-- ) { var precedentTick : Boolean = false; /** * Boucle qui parcours les pixels pour chaque colonne du haut vers le bas de l'image */ for( ordinate = 0; ordinate < bitmapData.height; ordinate++ ) { point = new Point(); color = bitmapData.getPixel( index, ordinate ); red = color >> 16 & 0xFF; green = color >> 8 & 0xFF; blue = color & 0xFF; grey = ( red + green + blue ) / 3; /** * Détection d'une écographie en nuance de gris, calculs du minimum et du maximum de l'échelle trouvée. */ if( greyScaleDetected && greyScaleArray.length < 40 ) { startY = 0; endY = 0; if( greyScaleArray.length > 2 && greyScaleArray.length < 30 ) { startY = greyScaleArray[ 0 ].y; endY = greyScaleArray[ greyScaleArray.length - 1 ].y; } if( ( endY - startY ) > bitmapData.height * 0.4 ) { distanceCounter = 0; tickCounter = 0; totalDistances = new Array(); for each( var greyPoint : Point in greyScaleArray ) { if( greyScaleArray.length == 3 ) { distanceFirstSegment = greyScaleArray[ 2 ].y - greyScaleArray[ 1 ].y; distanceSecondSegment = greyScaleArray[ 1 ].y - greyScaleArray[ 0 ].y; if( distanceFirstSegment < distanceSecondSegment + TOLERANCE && distanceFirstSegment > distanceSecondSegment - TOLERANCE ) { start = new Point( greyScaleArray[ 0 ].x, greyScaleArray[ 0 ].y ); end = new Point( greyScaleArray[ 0 ].x, greyScaleArray[ greyScaleArray.length - 1 ].y ); distance = end.y - start.y; scaleVo = new ScaleCjVo(); scaleVo.distance = distance; scaleVo.start = start; scaleVo.end = end; return scaleVo; } } else { if( temporaryPoint != null ) { minimum = ( greyPoint.y - temporaryPoint.y ) - TOLERANCE; maximum = ( greyPoint.y - temporaryPoint.y ) + TOLERANCE; if( distanceCounter < maximum && distanceCounter > minimum ) { tickCounter++; totalDistances.push( distanceCounter ); if( tickCounter == 2 ) { start = new Point( greyScaleArray[ 0 ].x, greyScaleArray[ 0 ].y ); end = new Point( greyScaleArray[ 0 ].x, greyScaleArray[ greyScaleArray.length - 1 ].y ); distance = end.y - start.y; if( greyScaleArray[ 0 ].y < 20 ) { start = new Point( greyScaleArray[ 1 ].x, greyScaleArray[ 1 ].y ); end = new Point( greyScaleArray[ 1 ].x, greyScaleArray[ greyScaleArray.length - 1 ].y ); } scaleVo = new ScaleCjVo(); scaleVo.distance = distance; scaleVo.start = start; scaleVo.end = end; if( distance > MINIMUM_DISTANCE ) { return scaleVo; } } } else { tickCounter = 0; totalDistances = new Array(); } distanceCounter = greyPoint.y - temporaryPoint.y; } temporaryPoint = greyPoint; } } } } } } return false; } } }