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

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

Completed linecluster with x position dectection, need to test

File size: 35.9 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 //CompareToOverride
148 //Compares start point y co ordinates of input PointArray
149 //With this. start point y co ordinate
150 @Override
151 public double compareTo(StartAndEndPoint comparePointArray){
152 Point comparePoint = (comparePointArray.getP1());
153 return (this.getP1().y) - (comparePoint.y);
154 }
155 */
156 }
157 public static <T> ArrayList<T> removeDuplicates(ArrayList<T> list) {
158 //DIRECTLY COPIED//DIRECTLY COPIED//DIRECTLY COPIED//DIRECTLY COPIED//DIRECTLY COPIED//DIRECTLY COPIED
159 // Function to remove duplicates from an ArrayList
160 // Create a new ArrayList
161 ArrayList<T> newList = new ArrayList();
162 // Traverse through the first list
163 for (T element : list) {
164 // If this element is not present in newList
165 // then add it
166 if (!newList.contains(element)) {
167 newList.add(element);
168 }
169 }
170 // return the new list
171 return newList;
172 //DIRECTLY COPIED//DIRECTLY COPIED//DIRECTLY COPIED//DIRECTLY COPIED//DIRECTLY COPIED//DIRECTLY COPIED
173 }
174 public static double StandardDeviation(double parseArray[]) {
175
176 double mean;
177 double sum =0.0;
178 double standardDeviation = 0.0;
179 //calculate sum of array
180 for(int i =0; i < parseArray.length; i++){
181 sum += parseArray[i];
182 }
183 //calculate mean of array
184 mean = sum/parseArray.length;
185 //calculate SD of array
186 for(int j =0; j < parseArray.length; j++){
187 standardDeviation += Math.pow(parseArray[j]-mean, 2);
188 }
189 return Math.sqrt(standardDeviation/parseArray.length);
190
191
192 }
193 public static double VarianceCalc(StartAndEndPoint parseArray[]){
194 double sum =0;
195 double temp =0;
196 double mean, variance;
197 int size = parseArray.length;
198 //Calculate sum of array
199 for(int i =0; i < parseArray.length; i++){
200 sum += parseArray[i].getP1().y;
201 }
202 //Calculate mean of array
203 mean = sum/parseArray.length;
204 //Calculate variants
205 for(int i =0; i < size; i++){
206 temp += Math.pow((parseArray[i].getP1().y-mean),2);
207 }
208 variance = Math.abs(temp/(size -1));
209 //System.out.println("VARIANCE: " + variance);
210 return variance;
211 }
212 public static Boolean lineComparison(double baseLineS, double compareLineS, double compareLineE ){
213 if(baseLineS < compareLineE && baseLineS > compareLineS){
214 return true;
215 }
216 return false;
217 }
218 public static Boolean ClusterCheck(StartAndEndPoint parseArray[]){
219 try {
220 //System.out.println("LENGTH: " + parseArray.length);
221 //MAKE THREE COMPARISONS
222 //After clusters have been found.
223 //Check if their x positions intersect
224 //Logic being
225 //(L1.S < L2.E && L1.S > L2.S)
226 //or
227 //(L2.S < L1.E && L2.S > L1.S)
228 //Variance is using Start of line point.
229 //USING VARIANTS
230 double variance = VarianceCalc(parseArray);
231 Boolean consistent = false;
232 if (variance <= CLUSTER_DISTANCE_MAX && variance > CLUSTER_DISTANCE_MIN) {
233 for (int i = 0; i < parseArray.length - 1; i++) {
234 //System.out.println(i);
235 double l1_S = parseArray[i].getP1().x;
236 double l1_E = parseArray[i].getP2().x;
237 double l2_S = parseArray[i + 1].getP1().x;
238 double l2_E = parseArray[i + 1].getP2().x;
239
240 //Check which starts after
241 if (l1_S >= l2_S) {
242 //baseLineStart is l1_S (call with lineComparison)
243 consistent = lineComparison(l1_S, l2_S, l2_E);
244 } else if (l2_S > l1_S) {
245 //baseLineStart is l2_S (call with lineComparison)
246 consistent = lineComparison(l2_S, l1_S, l1_E);
247 } else {
248 System.err.println("An error, comparing l1_S and l2_S, has occurred");
249 }
250
251 //Check if false was returned;
252 if (consistent == false) {
253 /*System.out.print(" X positions of two lines did not overlap each other:" + '\t');
254 System.out.print("l1_S: " + l1_S + '\t');
255 System.out.print("l1_E: " + l1_E + '\t');
256 System.out.print("l2_S: " + l2_S + '\t');
257 System.out.print("l2_E: " + l2_E);
258 System.out.println(" ");*/
259 return false;
260 }
261 }
262 //Have been through for loop, maintaining consistent being true.
263 //Have also meet the variance MIN and MAX requirement. Therefore it is a cluster
264 return true;
265 }
266 //System.out.println("Did not meet Cluster Distance Min and Max requirements, Variance = " + variance);
267 return false;
268 }
269 catch (Exception e){
270 System.err.println(" "+e.getMessage());
271 return false;
272 }
273 }
274
275
276 //CLASSIFYING FUNCTIONS
277 private static BufferedImage toBufferedImage(Mat mat){
278 //MOSTLY COPY PASTE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
279 //MOSTLY COPY PASTE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
280 //https://riptutorial.com/opencv/example/21963/converting-an-mat-object-to-an-bufferedimage-object
281 try{
282 int type = BufferedImage.TYPE_3BYTE_BGR;
283 int bufferSize = mat.channels() * mat.cols() * mat.rows();
284 byte[] b = new byte[bufferSize];
285 //get all the pixels
286 mat.get(0, 0, b);
287 BufferedImage image = new BufferedImage(mat.cols(), mat.rows(), type);
288 final byte[] targetPixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
289 System.arraycopy(b, 0, targetPixels, 0, b.length);
290 return image;
291 }
292 catch(Exception e){
293 System.err.println(e);
294 }
295 return null;
296 }
297 private static boolean ClassifierPixelCount(BufferedImage img){
298 try {
299 //Read file
300 //BufferedImage img = ImageIO.read(new File(processedFile));
301 int x = img.getWidth();
302 int y = img.getHeight();
303 int pixelCount = 0;
304 int redCount = 0;
305 float percentage = 0;
306
307 //Go Thru every pixel
308 for(int i=0; i < y; i++){
309 for(int j=0;j < x; j++){
310 //Get value for current pixels RGB value
311 int currPixelRGB = img.getRGB(j, i);
312 //Check if pixel is red (hex value of red)
313 if(currPixelRGB == 0xFFFF0000){
314 redCount++;
315 }
316 pixelCount++;
317 }
318 }
319 //Calculate percentage of Red in image
320 percentage = ((float)redCount/(float)pixelCount)*(float)100;
321 //If more than %10 and less than %50 then its sheet music!
322 if(percentage > CLASSIFIER_HOUGHLINESP_MIN && percentage < CLASSIFIER_HOUGHLINESP_MAX){ //MAKE THESE CONSTANTS!!
323 return true;}
324 }
325 catch (Exception e) {
326 System.err.println(e);
327 }
328 return false;
329 }
330 private static boolean ClassifierLineCount(int lineCount){
331
332 if(lineCount>MINLINECOUNT){
333 return true;
334 }
335 else{
336 return false;
337 }
338 }
339 private static ArrayList ClassifierLineClusterOLD(BufferedImage img){
340 ArrayList returnArray = new ArrayList();
341 try {
342
343 //IF THIS WORKS THEN IMPLEMENT A VERSION THAT USES POINTS from the draw line code.
344 //ALSO CHECK OUT K NEAREST NEIGHBOR?
345 //0xFFFF0000 = RED
346
347 //go thru every pixel until find red pixel
348 //get y pos of red pixel
349 //continue with loop until find another red pixel
350 //get y pos of red pixel
351 //compare y pos (if close together then continue loop) else break
352
353 int x = img.getWidth();
354 int y = img.getHeight();
355 int closeLineCount = 0;
356 ArrayList<Integer> redPixelYpos = new ArrayList<Integer>();
357
358 //Go Thru every pixel
359 for(int i=0; i < y; i++){
360 for(int j=0;j < x; j++){
361 //Get value for current pixels RGB value
362 int currPixelRGB = img.getRGB(j, i);
363 //Check if pixel is red (hex value of red)
364 if(currPixelRGB == 0xFFFF0000) {
365
366 //Store y pos of red pixel if there is no duplicate
367 if(!redPixelYpos.contains(i)){
368 redPixelYpos.add(i);
369 //System.out.println(i );
370 }
371 }
372 }
373 }
374 //Check if any of the lines found are close together and that there has been more than one line found
375 if(redPixelYpos.size()>1){
376 //go through list and compare every value
377 for(int i =0; i< redPixelYpos.size(); i++){
378 //System.out.println("i: " +redPixelYpos.get(i));
379 for(int j=0; j< redPixelYpos.size(); j++){
380 //System.out.println("j: "+redPixelYpos.get(j));
381 //Check if difference is less than 4 and the values are not duplicates.
382 if(Math.abs(redPixelYpos.get(i) - redPixelYpos.get(j)) < 4 && !redPixelYpos.get(j).equals(redPixelYpos.get(i))){
383 closeLineCount++;
384 }
385 }
386 }
387 }
388 int clusterCount = closeLineCount/4;
389
390 if(closeLineCount >= 4){
391 returnArray.add(true);
392 returnArray.add(closeLineCount);
393 returnArray.add(clusterCount);
394 }
395 else{
396 returnArray.add(false);
397 returnArray.add(closeLineCount);
398 returnArray.add(clusterCount);
399 }
400 }
401 catch (Exception e) {
402 System.err.println(e);
403 }
404 return returnArray;
405 }
406 private static ArrayList ClassifierLineCluster(ArrayList<StartAndEndPoint> linePointsArray, Mat clustersFoundRGB){
407
408 /*
409 ADDITION:
410 After clusters have been found.
411 Check if x positions intersect at all
412 StartXPos of p1
413
414 This will check for a cluster of lines that are close together.
415 1. Go through the list of Y positions(start point) in parsed array.
416 If, there is a small distance between them,
417 then, add to closeLineArray.
418
419 Have all Y positions that are close to each other now.
420 Need to find the lines that are clustered together.
421
422 Now check if there are four of these are close to each other.
423 2. Go through list of closeLine.
424 Get first four lines, traversing down a step each iteration {0,1,2,3} -> {1,2,3,4} -> {2,3,4,5}
425 If, those 4 lines are close together,
426 Then, add them to a new array that holds Line Cluster Values.
427 Go to line 4 positions down since, as do not want duplicates.
428
429 3.
430 */
431
432 ArrayList returnArray = new ArrayList();
433 ArrayList<Double> closeLineYPos = new ArrayList();
434 ArrayList<double[]> clusterArray = new ArrayList();
435 int clusterCount = 0;
436 try {
437 if(linePointsArray.size()> 1) {
438
439 /*
440 //Display input array TESTING PURPOSES
441 for (int i = 0; i < linePointsArray.size(); i++) {
442 System.out.println(linePointsArray.get(i).toString());
443 }
444 */
445
446 //1. Check if y points are close together
447 //go thru list and compare values against each other
448 for (int i = 0; i < linePointsArray.size(); i++){
449 //System.out.println("i: "+ linePointsArray.get(i).getP1().y);
450 for (int j = 0; j < linePointsArray.size(); j++) {
451 //System.out.println("j: "+ linePointsArray.get(j).getP1().y);
452 //Check if difference is less than 4 and the values are not duplicates.
453 if(Math.abs(linePointsArray.get(j).getP1().y - linePointsArray.get(i).getP1().y) < 5){
454 if(linePointsArray.get(j).getP1().y != linePointsArray.get(i).getP1().y){
455 closeLineYPos.add(linePointsArray.get(j).getP1().y);
456
457 }
458 }
459 }
460 }
461 /*for (double num : closeLineYPos){
462 System.out.println(num);
463 } */
464
465 //2. Now check if there are four of these are close to each other.
466 //Go through all of the items in this list and check if four of them are close together
467 //Check first four items, traverse down a step {0,1,2,3} -> {1,2,3,4} -> {2,3,4,5}
468 //If 4 items are close together,
469 //Then add them to a new array that holds Line Cluster Values.
470 //Go down 4 positions down since, as do not want duplicates.
471
472 //Now have an array of at least four lines that are close together.
473 //Sort array and remove duplicates
474 Collections.sort(closeLineYPos);
475
476
477
478 closeLineYPos = removeDuplicates(closeLineYPos);
479
480 //DISPLAYING AS EXCEPTED! WOO!
481
482 for (double y : closeLineYPos){
483 System.out.println("CloseLineYPos: " + y);
484 }
485 if(closeLineYPos.size() >= 4) {
486 //FOR every item in array of CloseLines
487 for(int i= 0; i< closeLineYPos.size(); i++){
488 //If last comparator is at end of array.
489 if(i + 4 >= closeLineYPos.size()){
490 break;
491 }
492 else{
493
494 //Add 4 values of CloseLine Array to a tempArray
495 double[] tempArray = new double[4];
496 tempArray[0] = closeLineYPos.get(i);
497 tempArray[1] = closeLineYPos.get(i + 1);
498 tempArray[2] = closeLineYPos.get(i + 2);
499 tempArray[3] = closeLineYPos.get(i + 3);
500
501 //Check standard deviation between these 4 values.
502 //If it SD is less than 5 then it is considered to be a cluster of lines.
503
504
505 if(StandardDeviation(tempArray) < STANDARD_DEVIATION_THRESHOLD){
506 //System.out.println("tempArray PT: "+tempArray[0] + " , " + tempArray[1] + " , " + tempArray[2] + " , " + tempArray[3]);
507 //System.out.println("tempArray SD: " + StandardDeviation(tempArray));
508 //Store array
509 clusterArray.add(tempArray);
510 //If I + 4 is less than the size of the array then increment by 4
511 //Go down +4 positions in closeLineYPos array
512 if((i + 4 < closeLineYPos.size())){
513 //System.out.println("IF, i = " + i + " -> "+ (i+4) + ", CloseLineYpos size= " + closeLineYPos.size());
514 i = i+4;
515 }
516 else{
517 //break
518 //System.out.println("ELSE, i = " + i+ " closeLineYpos size= " + closeLineYPos.size());
519 Thread.sleep(2000);
520 break;
521 }
522 }
523 }
524 }
525 }
526 /*
527 System.out.println("Cluster Coordinates: ");
528 for(double[] items : clusterArray){
529 for(int i = 0; i <items.length; i++){
530 System.out.println("ITEMS: "+ items[i]);
531 }
532 }
533 */
534 //Setup Drawing clusters found.
535 //For every pt given the input array
536 for(StartAndEndPoint pt : linePointsArray){
537 //Go through every the Arrays in the clusterArray(clustered lines)
538 for(int i =0; i < clusterArray.size(); i++){
539 //Go through every item in the array
540 for(double item : clusterArray.get(i)) {
541 //Check if the curr item is equal to current pt
542 if (item == pt.getP1().y){
543 //calculate a different colour for each line
544
545 //Draw a line
546 Imgproc.line(clustersFoundRGB, pt.getP1(), pt.getP2(), new Scalar(0, 255, 0), 1, Imgproc.LINE_4, 0);
547 }
548 }
549 }
550
551 }
552
553 clusterCount = clusterArray.size();
554 //SETUP RETURN ARRAY
555 if(clusterCount >= 1){
556 returnArray.add(true);
557 returnArray.add(closeLineYPos.size());
558 returnArray.add(clusterCount);
559 returnArray.add(clustersFoundRGB);
560 }
561 else{
562 returnArray.add(false);
563 returnArray.add(closeLineYPos.size());
564 returnArray.add(clusterCount);
565 }
566 }
567 }
568 catch (Exception e) {
569 System.err.println(e);
570 }
571 return returnArray;
572 }
573 private static ArrayList ClassifierLineClusterPt(ArrayList<StartAndEndPoint> linePointsArray, Mat clustersFoundRGB){
574 /*
575 ADDITION:
576 This will check for a cluster of lines that are close together.
577 1. Go through the list of Y positions(start point) in parsed array.
578 If, there is a small distance between them,
579 then, add to closeLineArray.
580
581 Have all Y positions that are close to each other now.
582 Need to find the lines that are clustered together.
583
584 Now check if there are four of these are close to each other.
585 2. Go through list of closeLine.
586 Get first four lines, traversing down a step each iteration {0,1,2,3} -> {1,2,3,4} -> {2,3,4,5}
587 If, those 4 lines are close together,
588 Then, add them to a new array that holds Line Cluster Values.
589 Go to line 4 positions down since, as do not want duplicates.
590
591 3.
592 */
593 ArrayList returnArray = new ArrayList();
594 ArrayList<StartAndEndPoint> closeLinePts = new ArrayList();
595 ArrayList<StartAndEndPoint[]> clusterPtArray = new ArrayList();
596 int clusterCount = 0;
597 try {
598 if(linePointsArray.size()> 1) {
599 /*
600 //Display input array TESTING PURPOSES
601 for (int i = 0; i < linePointsArray.size(); i++) {
602 System.out.println(linePointsArray.get(i).toString());
603 }
604 */
605 //1. Check if y points are close together
606 //go thru list and compare values against each other
607 for (int i = 0; i < linePointsArray.size(); i++){
608 //System.out.println("i: "+ linePointsArray.get(i).getP1().y);
609 for (int j = 0; j < linePointsArray.size(); j++) {
610 //System.out.println("j: "+ linePointsArray.get(j).getP1().y);
611 //Check if difference is less than 4 and the values are not duplicates.
612 if(Math.abs(linePointsArray.get(j).getP1().y - linePointsArray.get(i).getP1().y) < 5){
613 if(linePointsArray.get(j).getP1().y != linePointsArray.get(i).getP1().y){
614 closeLinePts.add(linePointsArray.get(i));
615 }
616 }
617 }
618 }
619
620 //2. Now check if there are four of these are close to each other.
621 //Go through all of the items in this list and check if four of them are close together
622 //Check first four items, traverse down a step {0,1,2,3} -> {1,2,3,4} -> {2,3,4,5}
623 //If 4 items are close together,
624 //Then add them to a new array that holds Line Cluster Values.
625 //Go down 4 positions down since, as do not want duplicates.
626
627 //Now have an array of at least four lines that are close together.
628 //Sort array and remove duplicates
629 Collections.sort(closeLinePts, new Comparator<StartAndEndPoint>() {
630 @Override
631 public int compare(StartAndEndPoint p1, StartAndEndPoint p2) {
632 return (int)(p1.getP1().y - p2.getP1().y);
633 }
634 });
635 closeLinePts = removeDuplicates(closeLinePts);
636 //DISPLAYING AS EXCEPTED! WOO!
637 /*for (StartAndEndPoint pt : closeLinePts) {
638 System.out.println("CloseLinePTs: " + pt.getP1().y);
639 }*/
640
641
642 if(closeLinePts.size() >= 4) {
643 //FOR every item in array of CloseLines
644 for(int i= 0; i < closeLinePts.size(); i++){
645 //If last comparator is at end of array.
646 if(i + 4 >= closeLinePts.size()){
647 break;
648 }
649 else{
650 //Add 4 values of CloseLinePt Array to a tempArray
651 StartAndEndPoint[] tempPtArray = new StartAndEndPoint[4];
652 tempPtArray[0] = closeLinePts.get(i);
653 tempPtArray[1] = closeLinePts.get(i + 1);
654 tempPtArray[2] = closeLinePts.get(i + 2);
655 tempPtArray[3] = closeLinePts.get(i + 3);
656
657 //Check standard deviation between these 4 values.
658 //If it SD is less than 5 then it is considered to be a cluster of lines.
659 if(ClusterCheck(tempPtArray)){
660 //System.out.println("tempArray PT: "+tempArray[0] + " , " + tempArray[1] + " , " + tempArray[2] + " , " + tempArray[3]);
661 //System.out.println("tempArray SD: " + StandardDeviation(tempArray));
662 //Store array
663 clusterPtArray.add(tempPtArray);
664 //If I + 4 is less than the size of the array then increment by 4
665 //Go down +4 positions in closeLineYPos array
666 if((i + 4 < closeLinePts.size())){
667 //System.out.println("IF, i = " + i + " -> "+ (i+4) + ", CloseLineYpos size= " + closeLineYPos.size());
668 i = i+4;
669 }
670 else{
671 //break
672 Thread.sleep(2000);
673 System.out.println("End of closeLinePts -> break , i = " + i+ " closeLineYpos size= " + closeLinePts.size());
674 break;
675 }
676 }
677 }
678 }
679 }
680 /*
681 System.out.println("Cluster Coordinates: ");
682 for(double[] items : clusterArray){
683 for(int i = 0; i <items.length; i++){
684 System.out.println("ITEMS: "+ items[i]);
685 }
686 }
687 */
688 //Setup Drawing clusters found.
689 //For every pt given the input array
690 for(StartAndEndPoint pt : linePointsArray){
691 //Go through every the Arrays in the clusterArray(clustered lines)
692 for(int i =0; i < clusterPtArray.size(); i++){
693 //Go through every item in the array
694 for(StartAndEndPoint item : clusterPtArray.get(i)) {
695 //Check if the curr item is equal to current pt
696 if (item.getP1().y == pt.getP1().y){
697 //calculate a different colour for each line
698 //Draw a line
699 Imgproc.line(clustersFoundRGB, pt.getP1(), pt.getP2(), new Scalar(0, 255, 0), 1, Imgproc.LINE_4, 0);
700 }
701 }
702 }
703 }
704
705 clusterCount = clusterPtArray.size();
706 //SETUP RETURN ARRAY
707 if(clusterCount >= 1){
708 returnArray.add(true);
709 returnArray.add(clusterCount);
710 returnArray.add(clustersFoundRGB);
711 }
712 else{
713 returnArray.add(false);
714 returnArray.add(clusterCount);
715 returnArray.add(clustersFoundRGB);
716 }
717 }
718 }
719 catch (Exception e) {
720 System.err.println(e.getMessage());
721 }
722 return returnArray;
723 }
724
725 //MAIN
726 public static void main(String[] args) {
727
728 System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
729
730 try {
731 ArrayList<StartAndEndPoint> pointArrayList = new ArrayList<>();
732
733 //Variables
734 Mat edgesDetected = new Mat();
735 Mat edgesDetectedRGB = new Mat();
736 Mat clustersFoundRGB = new Mat();
737 String directory = "/Scratch/cpb16/is-sheet-music-encore/download-images/MU/";
738 //!!!!!!!!!!!!!!!!!!!!!!!!!!!NOT!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
739 //mdp.39015097852365-2.png 176 lines Contents page.
740 //mdp.39015097852555-3.png 76 lines
741 //String default_file = directory+"SheetMusic/coo.31924062612282-9.png";
742 //String default_file ="TestImages/NotNot/mdp.39015080972303-3.png";
743
744
745 //System.out.println(default_file);
746 String default_file = "TestImages/NotSheetMusic01.png";
747 //String default_file = "TestImages/NotSheetMusic02.png";
748 //String default_file = "TestImages/SheetMusic01.png";
749 //String default_file = "TestImages/SheetMusic02.png";
750 //String default_file = "TestImages/vLine.png";
751 String filename = ((args.length > 0) ? args[0] : default_file);
752 File file = new File(filename);
753 if(!file.exists()){System.err.println("Image not found: "+ filename);}
754
755 int horizontalLineCount =0;
756
757 // Load an image
758 Mat original = Imgcodecs.imread(filename, Imgcodecs.IMREAD_GRAYSCALE);
759 // Edge detection
760 Imgproc.adaptiveThreshold(original, edgesDetected,255, Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C,Imgproc.THRESH_BINARY_INV, 15, 4);
761
762 //Convert to RGB for future use
763 Imgproc.cvtColor(edgesDetected, edgesDetectedRGB, Imgproc.COLOR_GRAY2BGR);
764 clustersFoundRGB = edgesDetectedRGB.clone();
765
766 Mat linesP = new Mat(); // will hold the results of the detection
767 //(edgeDetectedImage, outputOfDetection(r,Ξ), resolution of rho, resolution of theta, threshold (minimum num of intersections)
768
769 double minLineLength = edgesDetectedRGB.size().width/8;
770
771 Imgproc.HoughLinesP(edgesDetected, linesP, 1, Math.PI / 720, HOUGHLINEP_THRESHOLD, minLineLength,MAXLINEGAP); // runs the actual detection
772 //System.out.println("Before Gradient Filtering num lines: " + linesP.rows());
773
774 // Draw the lines
775 for (int x = 0; x < linesP.rows(); x++) {
776 double[] l = linesP.get(x, 0);
777 Point p1 = new Point(l[0], l[1]);
778 Point p2 = new Point(l[2], l[3]);
779 double m = Math.abs(p2.y - p1.y)/(p2.x - p1.x);
780
781 if(m<=SLOPEGRADIENT) {
782 Imgproc.line(edgesDetectedRGB, p1, p2, new Scalar(0, 0, 255), 1, Imgproc.LINE_4, 0);
783 horizontalLineCount++;
784 pointArrayList.add(new StartAndEndPoint(p1, p2));
785 }
786
787 }
788 //Point is a co ordinate (x, y)
789 //Prove by finding number of points from one end to other:
790 //Get width of image.
791 //File filenameTest = new File("TestImages/NotSheetMusic02.png");
792 //BufferedImage i = ImageIO.read(filenameTest);
793 BufferedImage toBeClassifiedImg = toBufferedImage(edgesDetectedRGB);
794
795
796
797 //Display Results
798 //HighGui.imshow("Source", original);
799 //HighGui.imshow("Just Edges", justEdges); //TESTING
800 HighGui.imshow("LINES FOUND", edgesDetectedRGB);
801 HighGui.imshow("CLUSTERS FOUND", clustersFoundRGB);
802
803 //HighGui.imshow("Detected Lines (in red) - negative", edgesDetectedRGBProb);
804
805
806
807 System.out.println("LINE COUNT RESULT: " + ClassifierLineCount(horizontalLineCount) + '\t' +"LinesFound: " + horizontalLineCount); //COUNT OF LINES CLASSIFICATION
808 //System.out.println("LINE CLUSTER RESULT: " + ClassifierLineClusterOLD(toBeClassifiedImg).get(0) + '\t' + "LinesFound: " + ClassifierLineClusterOLD(toBeClassifiedImg).get(1) + '\t' + "ClustersFound: " + ClassifierLineClusterOLD(toBeClassifiedImg).get(2));
809 System.out.println("NEW CLUSTER RESULTS: " + ClassifierLineClusterPt(pointArrayList,clustersFoundRGB).get(0) + '\t' + "LinesFound: " + horizontalLineCount + '\t' + "ClustersFound: " + ClassifierLineClusterPt(pointArrayList,clustersFoundRGB).get(1));
810 //System.out.println(ClassifierLineClusterPt(pointArrayList, clustersFoundRGB));
811
812 // Wait and Exit
813 HighGui.waitKey();
814 System.exit(0);
815 }
816 catch(Exception e){
817 System.err.println(e);
818 }
819 }
820}
Note: See TracBrowser for help on using the repository browser.