source: other-projects/is-sheet-music-encore/trunk/image-identification-development/src/Main.java@ 33340

Last change on this file since 33340 was 33340, checked in by cpb16, 5 years ago

transferred backup of low res images. Classifiers work as expected. Updated javaAccuracyCalculator, now calculates overall rating correctly. Created gen-50-XX-ValidIDList.txt for the 10% high-res downloads. Done by selecting first 50 of each gen-500-XX-Valid.... .txt. Downloading high-res images after this backup

File size: 36.7 KB
Line 
1/*
2 StartAndEndPoint l1 = parseArray[i];
3 StartAndEndPoint l2 = parseArray[i+ 1];
4 //CHECK WHICH line starts after the other
5 //If l1 is starting after, then comparisons are based around l1.s
6 //System.out.println("l1: " + l1.getP1().x);
7 //System.out.println("l2: " + l2.getP1().x);
8
9 System.out.println("1.0: L1S: " + l1.getP1().x + " larger than L2S: " + l2.getP1().x);
10 if(l1.getP1().x > l2.getP1().x) {
11 System.out.println("1.1: Comparing L1S: " + l1.getP1().x + " less than L2E: " + l2.getP2().x);
12 if (l1.getP1().x < l2.getP2().x) {
13 //AND
14 System.out.println("1.2: Comparing L1S: " + l1.getP1().x + " larger than L2S: " + l2.getP1().x);
15 if (l1.getP1().x > l2.getP1().x) {
16 System.out.println("1: Success. NEXT");
17 //IT IS INTERSECTED
18 continue;
19 }
20 else {
21 //FAILED SECOND COMPARISON
22 System.out.println("1: Fail");
23 }
24 }
25 else {
26 System.out.println("Checking other line");
27 }
28 System.out.println("2.0: L2S: " + l2.getP1().x + " larger than L1S: " + l1.getP1().x);
29 }
30 //If l2 is starting after, then comparisons are based around l2.s
31 else if(l2.getP1().x > l1.getP1().x) {
32 System.out.println("2.1: Comparing L2S: " + l1.getP1().x + " less than L1E: " + l2.getP2().x);
33 if (l2.getP1().x < l1.getP2().x) {
34 //AND
35 System.out.println("2.2: Comparing L2S: " + l2.getP1().x + " larger than L1S: " + l1.getP1().x);
36 if (l2.getP1().x > l1.getP1().x) {
37 System.out.println("2: Success");
38 //IT IS INTERSECTED
39 //continue;
40 }
41 else {
42 //FAILED SECOND COMPARISON
43 System.out.println("2: Fail");
44 //return false;
45 }
46 }
47 else {
48 System.out.println("Failed second comparison RETURN FALSE");
49 return false;
50 }
51 //return false;
52 }
53 else{
54 System.out.println("NEITHER RETURN FALSE");
55 return false;
56 }
57 */
58
59import org.opencv.core.*;
60import org.opencv.core.Point;
61import org.opencv.highgui.HighGui;
62import org.opencv.imgcodecs.Imgcodecs;
63import org.opencv.imgproc.Imgproc;
64import org.opencv.photo.Photo;
65import static org.opencv.imgcodecs.Imgcodecs.imwrite;
66import java.awt.image.BufferedImage;
67import java.awt.image.DataBufferByte;
68import java.io.File;
69import java.util.ArrayList;
70import java.util.Collection;
71import java.util.Collections;
72import java.util.Comparator;
73import javax.imageio.ImageIO;
74
75//REFERENCES:
76//https://docs.opencv.org/3.4.3/d9/db0/tutorial_hough_lines.
77//https://stackoverflow.com/questions/43443309/count-red-pixel-in-a-given-image
78//https://www.wikihow.com/Calculate-Percentage-in-Java
79//https://riptutorial.com/opencv/example/21963/converting-an-mat-object-to-an-bufferedimage-object
80//https://beginnersbook.com/2013/12/java-arraylist-of-object-sort-example-comparable-and-comparator/
81//https://www.programiz.com/java-programming/examples/standard-deviation
82//https://www.geeksforgeeks.org/how-to-remove-duplicates-from-arraylist-in-java/
83//https://stackoverflow.com/questions/7988486/how-do-you-calculate-the-variance-median-and-standard-deviation-in-c-or-java/7988556
84//https://stackoverflow.com/questions/10396970/sort-a-list-that-contains-a-custom-class
85
86
87
88
89//GOAL for 21st
90
91
92//Classifier 01
93//Have args so can call "java image-identification-classifier01 XX XX"
94//args can be parameters in algorthim such as threshold or theta?
95//Run on 5000 images.
96//Record success rates
97//All done with makefile
98
99
100//But first understand houghline transform
101//Know what the algorithm being used is doing.
102//MAke constants for this classifier
103//Make java be able to run on CMD line
104
105public class Main {
106 //GLOBAL_CONSTANTS
107 static double CLUSTER_DISTANCE_MAX = 40;
108 static double CLUSTER_DISTANCE_MIN = 2;
109 static int CLASSIFIER_HOUGHLINESP_MIN = 10;
110 static int CLASSIFIER_HOUGHLINESP_MAX = 65;
111 static int HOUGHLINEP_THRESHOLD = 10;
112 static int STANDARD_DEVIATION_THRESHOLD = 6;
113 static int MINLINECOUNT = 40;
114 static int MAXLINEGAP = 1; //4
115 static double SLOPEGRADIENT = 0.02;
116
117 //DEPENDENT FUNCTIONS AND CLASSES
118 static class StartAndEndPoint {
119 //PRIVATES
120 private Point _p1;
121 private Point _p2;
122 //CONSTRUCTOR
123 public StartAndEndPoint(Point p1, Point p2){
124 _p1 = p1;
125 _p2 = p2;
126 }
127 //GETTERS
128 public Point getP1(){
129 return _p1;
130 }
131 public Point getP2(){
132 return _p2;
133 }
134 //SETTERS
135 public void setP1(Point p1){
136 _p1 = p1;
137 }
138 public void setP2(Point p2){
139 _p2 = p2;
140 }
141
142 //ToString
143 public String toString(){
144 return "Start: " + _p1 + " End: " + _p2;
145 }
146
147 }
148
149 public static <T> ArrayList<T> removeDuplicates(ArrayList<T> list) {
150 //DIRECTLY COPIED//DIRECTLY COPIED//DIRECTLY COPIED//DIRECTLY COPIED//DIRECTLY COPIED//DIRECTLY COPIED
151 // Function to remove duplicates from an ArrayList
152 // Create a new ArrayList
153 ArrayList<T> newList = new ArrayList();
154 // Traverse through the first list
155 for (T element : list) {
156 // If this element is not present in newList
157 // then add it
158 if (!newList.contains(element)) {
159 newList.add(element);
160 }
161 }
162 // return the new list
163 return newList;
164 //DIRECTLY COPIED//DIRECTLY COPIED//DIRECTLY COPIED//DIRECTLY COPIED//DIRECTLY COPIED//DIRECTLY COPIED
165 }
166 public static double StandardDeviation(double parseArray[]) {
167
168 double mean;
169 double sum =0.0;
170 double standardDeviation = 0.0;
171 //calculate sum of array
172 for(int i =0; i < parseArray.length; i++){
173 sum += parseArray[i];
174 }
175 //calculate mean of array
176 mean = sum/parseArray.length;
177 //calculate SD of array
178 for(int j =0; j < parseArray.length; j++){
179 standardDeviation += Math.pow(parseArray[j]-mean, 2);
180 }
181 return Math.sqrt(standardDeviation/parseArray.length);
182
183
184 }
185 public static double VarianceCalc(StartAndEndPoint parseArray[]){
186 double sum =0;
187 double temp =0;
188 double mean, variance;
189 int size = parseArray.length;
190 //Calculate sum of array
191 for(int i =0; i < parseArray.length; i++){
192 sum += parseArray[i].getP1().y;
193 }
194 //Calculate mean of array
195 mean = sum/parseArray.length;
196 //Calculate variants
197 for(int i =0; i < size; i++){
198 temp += Math.pow((parseArray[i].getP1().y-mean),2);
199 }
200 variance = Math.abs(temp/(size -1));
201 //System.out.println("VARIANCE: " + variance);
202 return variance;
203 }
204 public static Boolean lineComparison(double baseLineS, double compareLineS, double compareLineE ){
205 //System.out.print("Comparing baseLineS: " + baseLineS + " with compareLineE: " + compareLineE + " and compareLineS: " + compareLineS);
206 if(baseLineS < compareLineE && baseLineS > compareLineS){
207 return true;
208 }
209 return false;
210 }
211 public static Boolean ClusterCheck(StartAndEndPoint parseArray[]){
212 try {
213 //System.out.println("LENGTH: " + parseArray.length);
214 //MAKE THREE COMPARISONS
215 //After clusters have been found.
216 //Check if their x positions intersect
217 //Logic being
218 //(L1.S < L2.E && L1.S > L2.S)
219 //or
220 //(L2.S < L1.E && L2.S > L1.S)
221 //Variance is using Start of line point.
222 //USING VARIANTS
223 double variance = VarianceCalc(parseArray);
224 Boolean consistent = false;
225 if (variance <= CLUSTER_DISTANCE_MAX && variance > CLUSTER_DISTANCE_MIN) {
226
227 for (int i = 0; i < parseArray.length - 1; i++) {
228 //System.out.println(i);
229 double l1_S = parseArray[i].getP1().x;
230 double l1_E = parseArray[i].getP2().x;
231 double l2_S = parseArray[i + 1].getP1().x;
232 double l2_E = parseArray[i + 1].getP2().x;
233
234 //Check which starts after
235 if (l1_S >= l2_S) {
236 //baseLineStart is l1_S (call with lineComparison)
237 consistent = lineComparison(l1_S, l2_S, l2_E);
238 } else if (l2_S > l1_S) {
239 //baseLineStart is l2_S (call with lineComparison)
240 consistent = lineComparison(l2_S, l1_S, l1_E);
241 } else {
242 System.err.println("An error, comparing l1_S and l2_S, has occurred");
243 }
244
245 //Check if false was returned;
246 if (consistent == false) {
247 /*System.out.print(" X positions of two lines did not overlap each other:" + '\t');
248 System.out.print("l1_S: " + l1_S + '\t');
249 System.out.print("l1_E: " + l1_E + '\t');
250 System.out.print("l2_S: " + l2_S + '\t');
251 System.out.print("l2_E: " + l2_E);
252 System.out.println(" ");*/
253 return false;
254 }
255 }
256 //Have been through for loop, maintaining consistent being true.
257 //Have also meet the variance MIN and MAX requirement. Therefore it is a cluster
258 return true;
259 }
260 //System.out.println("Did not meet Cluster Distance Min and Max requirements, Variance = " + variance);
261 return false;
262 }
263 catch (Exception e){
264 System.err.println(" "+e.getMessage());
265 return false;
266 }
267 }
268
269
270 //CLASSIFYING FUNCTIONS
271 private static BufferedImage toBufferedImage(Mat mat){
272 //MOSTLY COPY PASTE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
273 //MOSTLY COPY PASTE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
274 //https://riptutorial.com/opencv/example/21963/converting-an-mat-object-to-an-bufferedimage-object
275 try{
276 int type = BufferedImage.TYPE_3BYTE_BGR;
277 int bufferSize = mat.channels() * mat.cols() * mat.rows();
278 byte[] b = new byte[bufferSize];
279 //get all the pixels
280 mat.get(0, 0, b);
281 BufferedImage image = new BufferedImage(mat.cols(), mat.rows(), type);
282 final byte[] targetPixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
283 System.arraycopy(b, 0, targetPixels, 0, b.length);
284 return image;
285 }
286 catch(Exception e){
287 System.err.println(e);
288 }
289 return null;
290 }
291 private static boolean ClassifierPixelCount(BufferedImage img){
292 try {
293 //Read file
294 //BufferedImage img = ImageIO.read(new File(processedFile));
295 int x = img.getWidth();
296 int y = img.getHeight();
297 int pixelCount = 0;
298 int redCount = 0;
299 float percentage = 0;
300
301 //Go Thru every pixel
302 for(int i=0; i < y; i++){
303 for(int j=0;j < x; j++){
304 //Get value for current pixels RGB value
305 int currPixelRGB = img.getRGB(j, i);
306 //Check if pixel is red (hex value of red)
307 if(currPixelRGB == 0xFFFF0000){
308 redCount++;
309 }
310 pixelCount++;
311 }
312 }
313 //Calculate percentage of Red in image
314 percentage = ((float)redCount/(float)pixelCount)*(float)100;
315 //If more than %10 and less than %50 then its sheet music!
316 if(percentage > CLASSIFIER_HOUGHLINESP_MIN && percentage < CLASSIFIER_HOUGHLINESP_MAX){ //MAKE THESE CONSTANTS!!
317 return true;}
318 }
319 catch (Exception e) {
320 System.err.println(e);
321 }
322 return false;
323 }
324 private static boolean ClassifierLineCount(int lineCount){
325
326 if(lineCount>MINLINECOUNT){
327 return true;
328 }
329 else{
330 return false;
331 }
332 }
333 private static ArrayList ClassifierLineClusterOLD(BufferedImage img){
334 ArrayList returnArray = new ArrayList();
335 try {
336
337 //IF THIS WORKS THEN IMPLEMENT A VERSION THAT USES POINTS from the draw line code.
338 //ALSO CHECK OUT K NEAREST NEIGHBOR?
339 //0xFFFF0000 = RED
340
341 //go thru every pixel until find red pixel
342 //get y pos of red pixel
343 //continue with loop until find another red pixel
344 //get y pos of red pixel
345 //compare y pos (if close together then continue loop) else break
346
347 int x = img.getWidth();
348 int y = img.getHeight();
349 int closeLineCount = 0;
350 ArrayList<Integer> redPixelYpos = new ArrayList<Integer>();
351
352 //Go Thru every pixel
353 for(int i=0; i < y; i++){
354 for(int j=0;j < x; j++){
355 //Get value for current pixels RGB value
356 int currPixelRGB = img.getRGB(j, i);
357 //Check if pixel is red (hex value of red)
358 if(currPixelRGB == 0xFFFF0000) {
359
360 //Store y pos of red pixel if there is no duplicate
361 if(!redPixelYpos.contains(i)){
362 redPixelYpos.add(i);
363 //System.out.println(i );
364 }
365 }
366 }
367 }
368 //Check if any of the lines found are close together and that there has been more than one line found
369 if(redPixelYpos.size()>1){
370 //go through list and compare every value
371 for(int i =0; i< redPixelYpos.size(); i++){
372 //System.out.println("i: " +redPixelYpos.get(i));
373 for(int j=0; j< redPixelYpos.size(); j++){
374 //System.out.println("j: "+redPixelYpos.get(j));
375 //Check if difference is less than 4 and the values are not duplicates.
376 if(Math.abs(redPixelYpos.get(i) - redPixelYpos.get(j)) < 4 && !redPixelYpos.get(j).equals(redPixelYpos.get(i))){
377 closeLineCount++;
378 }
379 }
380 }
381 }
382 int clusterCount = closeLineCount/4;
383
384 if(closeLineCount >= 4){
385 returnArray.add(true);
386 returnArray.add(closeLineCount);
387 returnArray.add(clusterCount);
388 }
389 else{
390 returnArray.add(false);
391 returnArray.add(closeLineCount);
392 returnArray.add(clusterCount);
393 }
394 }
395 catch (Exception e) {
396 System.err.println(e);
397 }
398 return returnArray;
399 }
400 private static ArrayList ClassifierLineCluster(ArrayList<StartAndEndPoint> linePointsArray, Mat clustersFoundRGB){
401
402 /*
403 ADDITION:
404 After clusters have been found.
405 Check if x positions intersect at all
406 StartXPos of p1
407
408 This will check for a cluster of lines that are close together.
409 1. Go through the list of Y positions(start point) in parsed array.
410 If, there is a small distance between them,
411 then, add to closeLineArray.
412
413 Have all Y positions that are close to each other now.
414 Need to find the lines that are clustered together.
415
416 Now check if there are four of these are close to each other.
417 2. Go through list of closeLine.
418 Get first four lines, traversing down a step each iteration {0,1,2,3} -> {1,2,3,4} -> {2,3,4,5}
419 If, those 4 lines are close together,
420 Then, add them to a new array that holds Line Cluster Values.
421 Go to line 4 positions down since, as do not want duplicates.
422
423 3.
424 */
425
426 ArrayList returnArray = new ArrayList();
427 ArrayList<Double> closeLineYPos = new ArrayList();
428 ArrayList<double[]> clusterArray = new ArrayList();
429 int clusterCount = 0;
430 try {
431 if(linePointsArray.size()> 1) {
432
433 /*
434 //Display input array TESTING PURPOSES
435 for (int i = 0; i < linePointsArray.size(); i++) {
436 System.out.println(linePointsArray.get(i).toString());
437 }
438 */
439
440 //1. Check if y points are close together
441 //go thru list and compare values against each other
442 for (int i = 0; i < linePointsArray.size(); i++){
443 //System.out.println("i: "+ linePointsArray.get(i).getP1().y);
444 for (int j = 0; j < linePointsArray.size(); j++) {
445 //System.out.println("j: "+ linePointsArray.get(j).getP1().y);
446 //Check if difference is less than 4 and the values are not duplicates.
447 if(Math.abs(linePointsArray.get(j).getP1().y - linePointsArray.get(i).getP1().y) < 5){
448 if(linePointsArray.get(j).getP1().y != linePointsArray.get(i).getP1().y){
449 closeLineYPos.add(linePointsArray.get(j).getP1().y);
450
451 }
452 }
453 }
454 }
455 /*for (double num : closeLineYPos){
456 System.out.println(num);
457 } */
458
459 //2. Now check if there are four of these are close to each other.
460 //Go through all of the items in this list and check if four of them are close together
461 //Check first four items, traverse down a step {0,1,2,3} -> {1,2,3,4} -> {2,3,4,5}
462 //If 4 items are close together,
463 //Then add them to a new array that holds Line Cluster Values.
464 //Go down 4 positions down since, as do not want duplicates.
465
466 //Now have an array of at least four lines that are close together.
467 //Sort array and remove duplicates
468 Collections.sort(closeLineYPos);
469
470
471
472 closeLineYPos = removeDuplicates(closeLineYPos);
473
474 //DISPLAYING AS EXCEPTED! WOO!
475
476 for (double y : closeLineYPos){
477 System.out.println("CloseLineYPos: " + y);
478 }
479 if(closeLineYPos.size() >= 4) {
480 //FOR every item in array of CloseLines
481 for(int i= 0; i< closeLineYPos.size(); i++){
482 //If last comparator is at end of array.
483 if(i + 4 >= closeLineYPos.size()){
484 break;
485 }
486 else{
487
488 //Add 4 values of CloseLine Array to a tempArray
489 double[] tempArray = new double[4];
490 tempArray[0] = closeLineYPos.get(i);
491 tempArray[1] = closeLineYPos.get(i + 1);
492 tempArray[2] = closeLineYPos.get(i + 2);
493 tempArray[3] = closeLineYPos.get(i + 3);
494
495 //Check standard deviation between these 4 values.
496 //If it SD is less than 5 then it is considered to be a cluster of lines.
497
498
499 if(StandardDeviation(tempArray) < STANDARD_DEVIATION_THRESHOLD){
500 //System.out.println("tempArray PT: "+tempArray[0] + " , " + tempArray[1] + " , " + tempArray[2] + " , " + tempArray[3]);
501 //System.out.println("tempArray SD: " + StandardDeviation(tempArray));
502 //Store array
503 clusterArray.add(tempArray);
504 //If I + 4 is less than the size of the array then increment by 4
505 //Go down +4 positions in closeLineYPos array
506 if((i + 4 < closeLineYPos.size())){
507 //System.out.println("IF, i = " + i + " -> "+ (i+4) + ", CloseLineYpos size= " + closeLineYPos.size());
508 i = i+4;
509 }
510 else{
511 //break
512 //System.out.println("ELSE, i = " + i+ " closeLineYpos size= " + closeLineYPos.size());
513 Thread.sleep(2000);
514 break;
515 }
516 }
517 }
518 }
519 }
520 /*
521 System.out.println("Cluster Coordinates: ");
522 for(double[] items : clusterArray){
523 for(int i = 0; i <items.length; i++){
524 System.out.println("ITEMS: "+ items[i]);
525 }
526 }
527 */
528 //Setup Drawing clusters found.
529 //For every pt given the input array
530 for(StartAndEndPoint pt : linePointsArray){
531 //Go through every the Arrays in the clusterArray(clustered lines)
532 for(int i =0; i < clusterArray.size(); i++){
533 //Go through every item in the array
534 for(double item : clusterArray.get(i)) {
535 //Check if the curr item is equal to current pt
536 if (item == pt.getP1().y){
537 //calculate a different colour for each line
538
539 //Draw a line
540 Imgproc.line(clustersFoundRGB, pt.getP1(), pt.getP2(), new Scalar(0, 255, 0), 1, Imgproc.LINE_4, 0);
541 }
542 }
543 }
544
545 }
546
547 clusterCount = clusterArray.size();
548 //SETUP RETURN ARRAY
549 if(clusterCount >= 1){
550 returnArray.add(true);
551 returnArray.add(closeLineYPos.size());
552 returnArray.add(clusterCount);
553 returnArray.add(clustersFoundRGB);
554 }
555 else{
556 returnArray.add(false);
557 returnArray.add(closeLineYPos.size());
558 returnArray.add(clusterCount);
559 }
560 }
561 }
562 catch (Exception e) {
563 System.err.println(e);
564 }
565 return returnArray;
566 }
567 private static ArrayList ClassifierLineClusterPt(ArrayList<StartAndEndPoint> linePointsArray, Mat clustersFoundRGB){
568 /*
569 ADDITION:
570 This will check for a cluster of lines that are close together.
571 1. Go through the list of Y positions(start point) in parsed array.
572 If, there is a small distance between them,
573 then, add to closeLineArray.
574
575 Have all Y positions that are close to each other now.
576 Need to find the lines that are clustered together.
577
578 Now check if there are four of these are close to each other.
579 2. Go through list of closeLine.
580 Get first four lines, traversing down a step each iteration {0,1,2,3} -> {1,2,3,4} -> {2,3,4,5}
581 If, those 4 lines are close together,
582 Then, add them to a new array that holds Line Cluster Values.
583 Go to line 4 positions down since, as do not want duplicates.
584
585 3.
586 */
587 ArrayList returnArray = new ArrayList();
588 ArrayList<StartAndEndPoint> closeLinePts = new ArrayList();
589 ArrayList<StartAndEndPoint[]> clusterPtArray = new ArrayList();
590 int clusterCount = 0;
591 try {
592 if(linePointsArray.size()> 1) {
593 /*
594 //Display input array TESTING PURPOSES
595 for (int i = 0; i < linePointsArray.size(); i++) {
596 System.out.println(linePointsArray.get(i).toString());
597 }
598 */
599 //1. Check if y points are close together
600 //go thru list and compare values against each other
601 for (int i = 0; i < linePointsArray.size(); i++){
602 //System.out.println("i: "+ linePointsArray.get(i).getP1().y);
603 for (int j = 0; j < linePointsArray.size(); j++) {
604 //System.out.println("j: "+ linePointsArray.get(j).getP1().y);
605 //Check if difference is less than 4 and the values are not duplicates.
606 if(Math.abs(linePointsArray.get(j).getP1().y - linePointsArray.get(i).getP1().y) < 5){
607 if(linePointsArray.get(j).getP1().y != linePointsArray.get(i).getP1().y){
608 closeLinePts.add(linePointsArray.get(i));
609 }
610 }
611 }
612 }
613
614 //2. Now check if there are four of these are close to each other.
615 //Go through all of the items in this list and check if four of them are close together
616 //Check first four items, traverse down a step {0,1,2,3} -> {1,2,3,4} -> {2,3,4,5}
617 //If 4 items are close together,
618 //Then add them to a new array that holds Line Cluster Values.
619 //Go down 4 positions down since, as do not want duplicates.
620
621 //Now have an array of at least four lines that are close together.
622 //Sort array and remove duplicates
623 Collections.sort(closeLinePts, new Comparator<StartAndEndPoint>() {
624 @Override
625 public int compare(StartAndEndPoint p1, StartAndEndPoint p2) {
626 return (int)(p1.getP1().y - p2.getP1().y);
627 }
628 });
629 closeLinePts = removeDuplicates(closeLinePts);
630 //DISPLAYING AS EXCEPTED! WOO!
631 /*for (StartAndEndPoint pt : closeLinePts) {
632 System.out.println("CloseLinePTs: " + pt.getP1().y);
633 }*/
634
635
636 if(closeLinePts.size() >= 4) {
637 //FOR every item in array of CloseLines
638 for(int i= 0; i < closeLinePts.size(); i++){
639 //If last comparator is at end of array.
640 if(i + 4 >= closeLinePts.size()){
641 break;
642 }
643 else{
644 //Add 4 values of CloseLinePt Array to a tempArray
645 StartAndEndPoint[] tempPtArray = new StartAndEndPoint[4];
646 tempPtArray[0] = closeLinePts.get(i);
647 tempPtArray[1] = closeLinePts.get(i + 1);
648 tempPtArray[2] = closeLinePts.get(i + 2);
649 tempPtArray[3] = closeLinePts.get(i + 3);
650
651 //Check standard deviation between these 4 values.
652 //If it SD is less than 5 then it is considered to be a cluster of lines.
653 if(ClusterCheck(tempPtArray)){
654 //System.out.println("tempArray PT: "+tempPtArray[0] + " , " + tempPtArray[1] + " , " + tempPtArray[2] + " , " + tempPtArray[3]);
655 //Store array
656 clusterPtArray.add(tempPtArray);
657 //If I + 4 is less than the size of the array then increment by 4
658 //Go down +4 positions in closeLineYPos array
659 if((i + 4 < closeLinePts.size())){
660 //System.out.println("IF, i = " + i + " -> "+ (i+4) + ", CloseLineYpos size= " + closeLineYPos.size());
661 i = i+4;
662 }
663 else{
664 //break
665 Thread.sleep(2000);
666 //System.out.println("End of closeLinePts -> break , i = " + i+ " closeLineYpos size= " + closeLinePts.size());
667 break;
668 }
669 }
670 }
671 }
672 }
673
674 /*System.out.println("Cluster Coordinates: ");
675 for(StartAndEndPoint[] items : clusterPtArray){
676 for(int i = 0; i <clusterPtArray.size(); i++){
677 System.out.println("ITEMS: "+ items);
678 }
679 }*/
680
681 //Setup Drawing clusters found.
682 //For every pt given the input array
683 for(StartAndEndPoint pt : linePointsArray){
684 //Go through every the Arrays in the clusterArray(clustered lines)
685 for(int i =0; i < clusterPtArray.size(); i++){
686 //Go through every item in the array
687 for(StartAndEndPoint item : clusterPtArray.get(i)) {
688 //Check if the curr item is equal to current pt
689 if (item.getP1().y == pt.getP1().y){
690 //calculate a different colour for each line
691 //Draw a line
692 Imgproc.line(clustersFoundRGB, pt.getP1(), pt.getP2(), new Scalar(0, 255, 0), 1, Imgproc.LINE_4, 0);
693 }
694 }
695 }
696 }
697
698 clusterCount = clusterPtArray.size();
699 //SETUP RETURN ARRAY
700 if(clusterCount >= 1){
701 returnArray.add(true);
702 returnArray.add(clusterCount);
703 returnArray.add(clustersFoundRGB);
704 }
705 else{
706 returnArray.add(false);
707 returnArray.add(clusterCount);
708 returnArray.add(clustersFoundRGB);
709 }
710 }
711 }
712 catch (Exception e) {
713 System.err.println(e.getMessage());
714 }
715 return returnArray;
716 }
717
718 //SUPER CLASSIFIER FUNCTIONS
719 private static boolean LineCountOrCluster(int lineCount, ArrayList<StartAndEndPoint> linePointsArray, Mat clustersFoundRGB){
720 ArrayList lineClusterResult = ClassifierLineClusterPt(linePointsArray, clustersFoundRGB);
721
722
723 //String test = ClassifierLineClusterPt(linePointsArray, clustersFoundRGB).get(0).toString();
724 if(ClassifierLineCount(lineCount) == true){
725 System.out.println("LineCount classifier Successful: " + '\t' +"LinesFound: " + lineCount);
726 return true;
727 }
728 else if(lineClusterResult.get(0).toString() == "true"){
729 System.out.println("LineCluster classifier Successful: " + '\t' + "LinesFound: " + lineCount + '\t' + "ClustersFound: " + lineClusterResult.get(1));
730
731 return false;
732 }
733 return false;
734 }
735
736 //MAIN
737 public static void main(String[] args) {
738
739 System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
740
741 try {
742 ArrayList<StartAndEndPoint> pointArrayList = new ArrayList<>();
743
744 //Variables
745 Mat edgesDetected = new Mat();
746 Mat edgesDetectedRGB = new Mat();
747 Mat clustersFoundRGB = new Mat();
748 String directory = "/Scratch/cpb16/is-sheet-music-encore/lowres-download-images/MU/";
749 //!!!!!!!!!!!!!!!!!!!!!!!!!!!NOT!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
750 //mdp.39015097852365-2.png 176 lines Contents page.
751 //mdp.39015097852555-3.png 76 lines
752 //!!!!!!!!!!!!!!!!!!!!!!!!!!!NOTNOT!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
753 //coo.31924062612282-9.png 8 lines
754 //String default_file = directory+"NotSheetMusic/coo.31924062612282-9.png";
755 //String default_file = directory+"NotSheetMusic/mdp.39015097852365-2.png";
756 String default_file ="TestImages/NotNot/mdp.39015080972303-3.png";
757
758
759 //System.out.println(default_file);
760 //String default_file = "TestImages/NotSheetMusic01.png";
761 //String default_file = "TestImages/NotSheetMusic02.png";
762 //String default_file = "TestImages/SheetMusic01.png";
763 //String default_file = "TestImages/SheetMusic02.png";
764 //String default_file = "TestImages/vLine.png";
765 String filename = ((args.length > 0) ? args[0] : default_file);
766 File file = new File(filename);
767 if(!file.exists()){System.err.println("Image not found: "+ filename);}
768
769 int horizontalLineCount =0;
770
771 // Load an image
772 Mat original = Imgcodecs.imread(filename, Imgcodecs.IMREAD_GRAYSCALE);
773 // Edge detection
774 Imgproc.adaptiveThreshold(original, edgesDetected,255, Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C,Imgproc.THRESH_BINARY_INV, 15, 4);
775
776 //Convert to RGB for future use
777 Imgproc.cvtColor(edgesDetected, edgesDetectedRGB, Imgproc.COLOR_GRAY2BGR);
778 clustersFoundRGB = edgesDetectedRGB.clone();
779
780 Mat linesP = new Mat(); // will hold the results of the detection
781 //(edgeDetectedImage, outputOfDetection(r,Ξ), resolution of rho, resolution of theta, threshold (minimum num of intersections)
782
783 double minLineLength = edgesDetectedRGB.size().width/8;
784
785 Imgproc.HoughLinesP(edgesDetected, linesP, 1, Math.PI / 720, HOUGHLINEP_THRESHOLD, minLineLength,MAXLINEGAP); // runs the actual detection
786 //System.out.println("Before Gradient Filtering num lines: " + linesP.rows());
787
788 // Draw the lines
789 for (int x = 0; x < linesP.rows(); x++) {
790 double[] l = linesP.get(x, 0);
791 Point p1 = new Point(l[0], l[1]);
792 Point p2 = new Point(l[2], l[3]);
793 double m = Math.abs(p2.y - p1.y)/(p2.x - p1.x);
794
795 if(m<=SLOPEGRADIENT) {
796 Imgproc.line(edgesDetectedRGB, p1, p2, new Scalar(0, 0, 255), 1, Imgproc.LINE_4, 0);
797 horizontalLineCount++;
798 pointArrayList.add(new StartAndEndPoint(p1, p2));
799 }
800
801 }
802 //Point is a co ordinate (x, y)
803 //Prove by finding number of points from one end to other:
804 //Get width of image.
805 //File filenameTest = new File("TestImages/NotSheetMusic02.png");
806 //BufferedImage i = ImageIO.read(filenameTest);
807 BufferedImage toBeClassifiedImg = toBufferedImage(edgesDetectedRGB);
808
809
810
811 //Display Results
812 //HighGui.imshow("Source", original);
813 //HighGui.imshow("Just Edges", justEdges); //TESTING
814 HighGui.imshow("LINES FOUND", edgesDetectedRGB);
815 HighGui.imshow("CLUSTERS FOUND", clustersFoundRGB);
816
817 //HighGui.imshow("Detected Lines (in red) - negative", edgesDetectedRGBProb);
818
819
820
821 //System.out.println("LINE COUNT RESULT: " + ClassifierLineCount(horizontalLineCount) + '\t' +"LinesFound: " + horizontalLineCount); //COUNT OF LINES CLASSIFICATION
822 //System.out.println("LINE CLUSTER RESULT: " + ClassifierLineClusterOLD(toBeClassifiedImg).get(0) + '\t' + "LinesFound: " + ClassifierLineClusterOLD(toBeClassifiedImg).get(1) + '\t' + "ClustersFound: " + ClassifierLineClusterOLD(toBeClassifiedImg).get(2));
823 //System.out.println("NEW CLUSTER RESULTS: " + ClassifierLineClusterPt(pointArrayList,clustersFoundRGB).get(0) + '\t' + "LinesFound: " + horizontalLineCount + '\t' + "ClustersFound: " + ClassifierLineClusterPt(pointArrayList,clustersFoundRGB).get(1));
824 //System.out.println(ClassifierLineClusterPt(pointArrayList, clustersFoundRGB));
825
826 System.out.println("TEST: " + LineCountOrCluster(horizontalLineCount, pointArrayList, clustersFoundRGB));
827
828 // Wait and Exit
829 HighGui.waitKey();
830 System.exit(0);
831 }
832 catch(Exception e){
833 System.err.println(e);
834 }
835 }
836}
Note: See TracBrowser for help on using the repository browser.