Changeset 33340 for other-projects/is-sheet-music-encore/trunk/image-identification-terminal/javaImageClassifier.java
- Timestamp:
- 2019-07-22T16:46:33+12:00 (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
other-projects/is-sheet-music-encore/trunk/image-identification-terminal/javaImageClassifier.java
r33304 r33340 7 7 import java.awt.image.BufferedImage; 8 8 import java.awt.image.DataBufferByte; 9 import java.io.File;10 import java.io.BufferedWriter;11 import java.io.FileWriter;9 //import java.io.File; 10 //import java.io.BufferedWriter; 11 //import java.io.FileWriter; 12 12 import javax.imageio.ImageIO; 13 import java.util.logging.Logger; 14 import java.util.ArrayList; 13 //import java.util.logging.Logger; 14 //import java.util.ArrayList; 15 //import java.util.Collections.*; 16 import java.util.*; 17 import java.lang.*; 18 import java.io.*; 15 19 16 20 //REFERENCES: … … 28 32 //False =classifierType + 0 + Filename + Status 29 33 public class javaImageClassifier{ 30 //Constants 31 34 //GLOBALS Constants 32 35 static int CLASSIFIER_HOUGHLINESP_MIN = 10; 33 36 static int CLASSIFIER_HOUGHLINESP_MAX = 65; 34 37 static int HOUGHLINEP_THRESHOLD = 10; 38 static int STANDARD_DEVIATION_THRESHOLD = 6; 35 39 static int MINLINECOUNT = 40; 36 static double MAXLINEGAP= 4;40 static int MAXLINEGAP = 4; 37 41 static double SLOPEGRADIENT = 0.02; 38 42 static double CLUSTER_DISTANCE_MAX = 40; 43 static double CLUSTER_DISTANCE_MIN = 2; 44 45 static class StartAndEndPoint { 46 //PRIVATES 47 private Point _p1; 48 private Point _p2; 49 //CONSTRUCTOR 50 public StartAndEndPoint(Point p1, Point p2){ 51 _p1 = p1; 52 _p2 = p2;} 53 //GETTERS 54 public Point getP1(){return _p1;} 55 public Point getP2(){return _p2;} 56 //SETTERS 57 public void setP1(Point p1){_p1 = p1;} 58 public void setP2(Point p2){_p2 = p2;} 59 //ToString 60 public String toString(){ 61 return "Start: " + _p1 + " End: " + _p2; 62 } 63 } 64 39 65 public static void main(String[] args) { 40 66 try { … … 45 71 ArrayList result_refined = null; 46 72 Boolean result = null; 73 String result_cluster = ""; 47 74 String imageFilename = args[0]; 48 75 String classifierType = args[1]; … … 65 92 bw.write("Filename:" + '\t' + imageFilename + '\t' + "Classified as:" + '\t' + result_refined.get(0) + '\t' + "Number of lines:" + '\t' + result_refined.get(1) + '\t' + classifierType + '\n'); 66 93 break; 94 case "cluster-detection": 95 //result_cluster = setup_Cluster(imageFilename); 96 //bw.write(result_cluster); 97 break; 67 98 default: 68 99 System.out.println("unknown algorithm"); … … 84 115 //CLASSIFIER FUNCTIONS 85 116 //****************** 86 private static Boolean setup_HoughLinesP(String filename){117 private static boolean setup_HoughLinesP(String filename){ 87 118 System.loadLibrary(Core.NATIVE_LIBRARY_NAME); 88 119 Boolean isSheetMusic = null; … … 118 149 return isSheetMusic; 119 150 } 120 121 private static ArrayList setup_HoughLinesP_refined(String filename){ 151 private static boolean classifier_HoughLinesP(BufferedImage img){ 152 System.loadLibrary(Core.NATIVE_LIBRARY_NAME); 153 try { 154 //Read file 155 int x = img.getWidth(); 156 int y = img.getHeight(); 157 int pixelCount = 0; 158 int redCount = 0; 159 float percentage = 0; 160 //Go Thru every pixel 161 for(int i=0; i < y; i++){ 162 for(int j=0;j < x; j++){ 163 //Get value for current pixels RGB value 164 int currPixelRGB = img.getRGB(j, i); 165 //Check if pixel is red (hex value of red) 166 if(currPixelRGB == 0xFFFF0000){ 167 redCount++; 168 } 169 pixelCount++; 170 } 171 } 172 //Calculate percentage of Red in image 173 percentage = ((float)redCount/(float)pixelCount)*(float)100; 174 //If more than %10 and less than %50 then its sheet music! 175 if(percentage > CLASSIFIER_HOUGHLINESP_MIN && percentage < CLASSIFIER_HOUGHLINESP_MAX){ 176 return true;} 177 } 178 catch (Exception e) { 179 System.err.println(e); 180 } 181 return false; 182 } 183 184 private static ArrayList setup_HoughLinesP_refined(String filename){ 122 185 System.loadLibrary(Core.NATIVE_LIBRARY_NAME); 123 186 Boolean isSheetMusic = null; 124 187 ArrayList returnArray = new ArrayList(); 125 188 try{ 126 127 189 //Variables 128 190 int horizontalLineCount =0; … … 134 196 Mat original = Imgcodecs.imread(filename, Imgcodecs.IMREAD_GRAYSCALE); 135 197 // Edge detection 136 //Imgproc.Canny(original, edgesDetected, 50, 200, 3, false);137 198 Imgproc.adaptiveThreshold(original, edgesDetected,255, Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C,Imgproc.THRESH_BINARY_INV,15, 2); 138 //Imgproc.blur(edgesExtra, edgesDetected, new Size(3,1));139 //Imgproc.medianBlur(edgesExtra, edgesDetected, 3);140 141 142 199 //Copy edges to the images that will display the results in BGR 143 200 Imgproc.cvtColor(edgesDetected, edgesDetectedRGB, Imgproc.COLOR_GRAY2BGR); … … 145 202 Mat linesP = new Mat(); // will hold the results of the detection 146 203 double minLineLength = edgesDetectedRGB.size().width/8; 147 //Imgproc.HoughLinesP(edgesDetected, linesP, 1, Math.PI / 180, 10, minLineLength, MAXLINEGAP);// runs the actual detection 148 Imgproc.HoughLinesP(edgesDetected, linesP, 1, Math.PI / 720, HOUGHLINEP_THRESHOLD, minLineLength, MAXLINEGAP); //TESTING 204 Imgproc.HoughLinesP(edgesDetected, linesP, 1, Math.PI / 720, HOUGHLINEP_THRESHOLD, minLineLength, MAXLINEGAP); 149 205 // Draw the lines 150 206 … … 179 235 return returnArray; 180 236 } 181 237 private static boolean classifier_HoughLinesP_refined(int lineCount){ 238 if(lineCount>MINLINECOUNT){ 239 return true; 240 } 241 else{ 242 return false; 243 } 244 } 245 246 // private static String setup_Cluster(String filename){ 247 // //NEED TO ADD IMAGE PROC, BEFORE THIS PART BELOW (ANALYSIS OF RESULTS) 248 // String returnString = ""; 249 // //ArrayList lineClusterResult = ClassifierLineClusterPt(linePointsArray, clustersFoundRGB); 250 // if(ClassifierLineCount(lineCount) == true){ 251 // returnString = "LineCount classifier Successful: " + '\t' +"LinesFound: " + lineCount; 252 // return returnString; 253 // } 254 // else if(lineClusterResult.get(0).toString() == "true"){ 255 // returnString = "LineCluster classifier Successful: " + '\t' + "LinesFound: " + lineCount + '\t' + "ClustersFound: " + lineClusterResult.get(1); 256 // return returnString; 257 // } 258 // return returnString; 259 // } 260 182 261 //****************** 183 262 //INTERNAL FUNCTIONS 184 263 //****************** 185 private static boolean classifier_HoughLinesP(BufferedImage img){ 186 System.loadLibrary(Core.NATIVE_LIBRARY_NAME); 187 try { 188 //Read file 189 int x = img.getWidth(); 190 int y = img.getHeight(); 191 int pixelCount = 0; 192 int redCount = 0; 193 float percentage = 0; 194 //Go Thru every pixel 195 for(int i=0; i < y; i++){ 196 for(int j=0;j < x; j++){ 197 //Get value for current pixels RGB value 198 int currPixelRGB = img.getRGB(j, i); 199 //Check if pixel is red (hex value of red) 200 if(currPixelRGB == 0xFFFF0000){ 201 redCount++; 202 } 203 pixelCount++; 204 } 205 } 206 //Calculate percentage of Red in image 207 percentage = ((float)redCount/(float)pixelCount)*(float)100; 208 //If more than %10 and less than %50 then its sheet music! 209 if(percentage > CLASSIFIER_HOUGHLINESP_MIN && percentage < CLASSIFIER_HOUGHLINESP_MAX){ 210 return true;} 211 } 212 catch (Exception e) { 213 System.err.println(e); 214 } 215 return false; 216 } 217 218 private static boolean classifier_HoughLinesP_refined(int lineCount){ 219 if(lineCount>MINLINECOUNT){ 220 return true; 221 } 222 else{ 223 return false; 224 } 225 } 226 227 private static BufferedImage toBufferedImage(Mat mat){ 264 265 private static BufferedImage toBufferedImage(Mat mat){ 228 266 //MOSTLY COPY PASTE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 229 267 //MOSTLY COPY PASTE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! … … 245 283 } 246 284 return null; 247 } 285 } 286 private static ArrayList ClassifierLineClusterPt(ArrayList<StartAndEndPoint> linePointsArray, Mat clustersFoundRGB){ 287 /* 288 ADDITION: 289 This will check for a cluster of lines that are close together. 290 1. Go through the list of Y positions(start point) in parsed array. 291 If, there is a small distance between them, 292 then, add to closeLineArray. 293 294 Have all Y positions that are close to each other now. 295 Need to find the lines that are clustered together. 296 297 Now check if there are four of these are close to each other. 298 2. Go through list of closeLine. 299 Get first four lines, traversing down a step each iteration {0,1,2,3} -> {1,2,3,4} -> {2,3,4,5} 300 If, those 4 lines are close together, 301 Then, add them to a new array that holds Line Cluster Values. 302 Go to line 4 positions down since, as do not want duplicates. 303 304 3. 305 */ 306 ArrayList returnArray = new ArrayList(); 307 ArrayList<StartAndEndPoint> closeLinePts = new ArrayList(); 308 ArrayList<StartAndEndPoint[]> clusterPtArray = new ArrayList(); 309 int clusterCount = 0; 310 try { 311 if(linePointsArray.size()> 1) { 312 /* 313 //Display input array TESTING PURPOSES 314 for (int i = 0; i < linePointsArray.size(); i++) { 315 System.out.println(linePointsArray.get(i).toString()); 316 } 317 */ 318 //1. Check if y points are close together 319 //go thru list and compare values against each other 320 for (int i = 0; i < linePointsArray.size(); i++){ 321 //System.out.println("i: "+ linePointsArray.get(i).getP1().y); 322 for (int j = 0; j < linePointsArray.size(); j++) { 323 //System.out.println("j: "+ linePointsArray.get(j).getP1().y); 324 //Check if difference is less than 4 and the values are not duplicates. 325 if(Math.abs(linePointsArray.get(j).getP1().y - linePointsArray.get(i).getP1().y) < 5){ 326 if(linePointsArray.get(j).getP1().y != linePointsArray.get(i).getP1().y){ 327 closeLinePts.add(linePointsArray.get(i)); 328 } 329 } 330 } 331 } 332 333 //2. Now check if there are four of these are close to each other. 334 //Go through all of the items in this list and check if four of them are close together 335 //Check first four items, traverse down a step {0,1,2,3} -> {1,2,3,4} -> {2,3,4,5} 336 //If 4 items are close together, 337 //Then add them to a new array that holds Line Cluster Values. 338 //Go down 4 positions down since, as do not want duplicates. 339 340 //Now have an array of at least four lines that are close together. 341 //Sort array and remove duplicates 342 Collections.sort(closeLinePts, new Comparator<StartAndEndPoint>() { 343 @Override 344 public int compare(StartAndEndPoint p1, StartAndEndPoint p2) { 345 return (int)(p1.getP1().y - p2.getP1().y); 346 } 347 }); 348 closeLinePts = removeDuplicates(closeLinePts); 349 //DISPLAYING AS EXCEPTED! WOO! 350 /*for (StartAndEndPoint pt : closeLinePts) { 351 System.out.println("CloseLinePTs: " + pt.getP1().y); 352 }*/ 353 354 355 if(closeLinePts.size() >= 4) { 356 //FOR every item in array of CloseLines 357 for(int i= 0; i < closeLinePts.size(); i++){ 358 //If last comparator is at end of array. 359 if(i + 4 >= closeLinePts.size()){ 360 break; 361 } 362 else{ 363 //Add 4 values of CloseLinePt Array to a tempArray 364 StartAndEndPoint[] tempPtArray = new StartAndEndPoint[4]; 365 tempPtArray[0] = closeLinePts.get(i); 366 tempPtArray[1] = closeLinePts.get(i + 1); 367 tempPtArray[2] = closeLinePts.get(i + 2); 368 tempPtArray[3] = closeLinePts.get(i + 3); 369 370 //Check standard deviation between these 4 values. 371 //If it SD is less than 5 then it is considered to be a cluster of lines. 372 if(ClusterCheck(tempPtArray)){ 373 //System.out.println("tempArray PT: "+tempPtArray[0] + " , " + tempPtArray[1] + " , " + tempPtArray[2] + " , " + tempPtArray[3]); 374 //Store array 375 clusterPtArray.add(tempPtArray); 376 //If I + 4 is less than the size of the array then increment by 4 377 //Go down +4 positions in closeLineYPos array 378 if((i + 4 < closeLinePts.size())){ 379 //System.out.println("IF, i = " + i + " -> "+ (i+4) + ", CloseLineYpos size= " + closeLineYPos.size()); 380 i = i+4; 381 } 382 else{ 383 //break 384 Thread.sleep(2000); 385 //System.out.println("End of closeLinePts -> break , i = " + i+ " closeLineYpos size= " + closeLinePts.size()); 386 break; 387 } 388 } 389 } 390 } 391 } 392 393 //System.out.println("Cluster Coordinates: "); 394 //for(StartAndEndPoint[] items : clusterPtArray){ 395 // for(int i = 0; i <clusterPtArray.size(); i++){ 396 // System.out.println("ITEMS: "+ items); 397 // } 398 //} 399 400 //Setup Drawing clusters found. 401 //For every pt given the input array 402 for(StartAndEndPoint pt : linePointsArray){ 403 //Go through every the Arrays in the clusterArray(clustered lines) 404 for(int i =0; i < clusterPtArray.size(); i++){ 405 //Go through every item in the array 406 for(StartAndEndPoint item : clusterPtArray.get(i)) { 407 //Check if the curr item is equal to current pt 408 if (item.getP1().y == pt.getP1().y){ 409 //calculate a different colour for each line 410 //Draw a line 411 Imgproc.line(clustersFoundRGB, pt.getP1(), pt.getP2(), new Scalar(0, 255, 0), 1, Imgproc.LINE_4, 0); 412 } 413 } 414 } 415 } 416 417 clusterCount = clusterPtArray.size(); 418 //SETUP RETURN ARRAY 419 if(clusterCount >= 1){ 420 returnArray.add(true); 421 returnArray.add(clusterCount); 422 returnArray.add(clustersFoundRGB); 423 } 424 else{ 425 returnArray.add(false); 426 returnArray.add(clusterCount); 427 returnArray.add(clustersFoundRGB); 428 } 429 } 430 } 431 catch (Exception e) { 432 System.err.println(e.getMessage()); 433 } 434 return returnArray; 435 } 436 private static boolean ClusterCheck(StartAndEndPoint parseArray[]){ 437 try { 438 //System.out.println("LENGTH: " + parseArray.length); 439 //MAKE THREE COMPARISONS 440 //After clusters have been found. 441 //Check if their x positions intersect 442 //Logic being 443 //(L1.S < L2.E && L1.S > L2.S) 444 //or 445 //(L2.S < L1.E && L2.S > L1.S) 446 //Variance is using Start of line point. 447 //USING VARIANTS 448 double variance = VarianceCalc(parseArray); 449 Boolean consistent = false; 450 if (variance <= CLUSTER_DISTANCE_MAX && variance > CLUSTER_DISTANCE_MIN) { 451 452 for (int i = 0; i < parseArray.length - 1; i++) { 453 //System.out.println(i); 454 double l1_S = parseArray[i].getP1().x; 455 double l1_E = parseArray[i].getP2().x; 456 double l2_S = parseArray[i + 1].getP1().x; 457 double l2_E = parseArray[i + 1].getP2().x; 458 459 //Check which starts after 460 if (l1_S >= l2_S) { 461 //baseLineStart is l1_S (call with lineComparison) 462 consistent = lineComparison(l1_S, l2_S, l2_E); 463 } else if (l2_S > l1_S) { 464 //baseLineStart is l2_S (call with lineComparison) 465 consistent = lineComparison(l2_S, l1_S, l1_E); 466 } else { 467 System.err.println("An error, comparing l1_S and l2_S, has occurred"); 468 } 469 470 //Check if false was returned; 471 if (consistent == false) { 472 /*System.out.print(" X positions of two lines did not overlap each other:" + '\t'); 473 System.out.print("l1_S: " + l1_S + '\t'); 474 System.out.print("l1_E: " + l1_E + '\t'); 475 System.out.print("l2_S: " + l2_S + '\t'); 476 System.out.print("l2_E: " + l2_E); 477 System.out.println(" ");*/ 478 return false; 479 } 480 } 481 //Have been through for loop, maintaining consistent being true. 482 //Have also meet the variance MIN and MAX requirement. Therefore it is a cluster 483 return true; 484 } 485 //System.out.println("Did not meet Cluster Distance Min and Max requirements, Variance = " + variance); 486 return false; 487 } 488 catch (Exception e){ 489 System.err.println(" "+e.getMessage()); 490 return false; 491 } 492 } 493 private static double VarianceCalc(StartAndEndPoint parseArray[]){ 494 double sum =0; 495 double temp =0; 496 double mean, variance; 497 int size = parseArray.length; 498 //Calculate sum of array 499 for(int i =0; i < parseArray.length; i++){ 500 sum += parseArray[i].getP1().y; 501 } 502 //Calculate mean of array 503 mean = sum/parseArray.length; 504 //Calculate variants 505 for(int i =0; i < size; i++){ 506 temp += Math.pow((parseArray[i].getP1().y-mean),2); 507 } 508 variance = Math.abs(temp/(size -1)); 509 //System.out.println("VARIANCE: " + variance); 510 return variance; 511 } 512 private static boolean lineComparison(double baseLineS, double compareLineS, double compareLineE ){ 513 //System.out.print("Comparing baseLineS: " + baseLineS + " with compareLineE: " + compareLineE + " and compareLineS: " + compareLineS); 514 if(baseLineS < compareLineE && baseLineS > compareLineS){ 515 return true; 516 } 517 return false; 518 } 519 private static <T> ArrayList<T> removeDuplicates(ArrayList<T> list) { 520 //DIRECTLY COPIED//DIRECTLY COPIED//DIRECTLY COPIED//DIRECTLY COPIED//DIRECTLY COPIED//DIRECTLY COPIED 521 // Function to remove duplicates from an ArrayList 522 // Create a new ArrayList 523 ArrayList<T> newList = new ArrayList(); 524 // Traverse through the first list 525 for (T element : list) { 526 // If this element is not present in newList 527 // then add it 528 if (!newList.contains(element)) { 529 newList.add(element); 530 } 531 } 532 // return the new list 533 return newList; 534 //DIRECTLY COPIED//DIRECTLY COPIED//DIRECTLY COPIED//DIRECTLY COPIED//DIRECTLY COPIED//DIRECTLY COPIED 535 } 536 /*private static boolean LineCountOrCluster(int lineCount, ArrayList<StartAndEndPoint> linePointsArray, Mat clustersFoundRGB){ 537 ArrayList lineClusterResult = ClassifierLineClusterPt(linePointsArray, clustersFoundRGB); 538 539 540 //String test = ClassifierLineClusterPt(linePointsArray, clustersFoundRGB).get(0).toString(); 541 if(ClassifierLineCount(lineCount) == true){ 542 System.out.println("LineCount classifier Successful: " + '\t' +"LinesFound: " + lineCount); 543 return true; 544 } 545 else if(lineClusterResult.get(0).toString() == "true"){ 546 System.out.println("LineCluster classifier Successful: " + '\t' + "LinesFound: " + lineCount + '\t' + "ClustersFound: " + lineClusterResult.get(1)); 547 548 return false; 549 } 550 return false; 551 }*/ 552 248 553 }
Note:
See TracChangeset
for help on using the changeset viewer.