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

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

Added x pos checker, needs testing, and remove errors

File size: 36.2 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 //DEPENDENT FUNCTIONS AND CLASSES
107 static class StartAndEndPoint {
108 //PRIVATES
109 private Point _p1;
110 private Point _p2;
111 //CONSTRUCTOR
112 public StartAndEndPoint(Point p1, Point p2){
113 _p1 = p1;
114 _p2 = p2;
115 }
116 //GETTERS
117 public Point getP1(){
118 return _p1;
119 }
120 public Point getP2(){
121 return _p2;
122 }
123 //SETTERS
124 public void setP1(Point p1){
125 _p1 = p1;
126 }
127 public void setP2(Point p2){
128 _p2 = p2;
129 }
130
131 //ToString
132 public String toString(){
133 return "Start: " + _p1 + " End: " + _p2;
134 }
135 /*
136 //CompareToOverride
137 //Compares start point y co ordinates of input PointArray
138 //With this. start point y co ordinate
139 @Override
140 public double compareTo(StartAndEndPoint comparePointArray){
141 Point comparePoint = (comparePointArray.getP1());
142 return (this.getP1().y) - (comparePoint.y);
143 }
144 */
145 }
146 public static <T> ArrayList<T> removeDuplicates(ArrayList<T> list) {
147 //DIRECTLY COPIED//DIRECTLY COPIED//DIRECTLY COPIED//DIRECTLY COPIED//DIRECTLY COPIED//DIRECTLY COPIED
148 // Function to remove duplicates from an ArrayList
149 // Create a new ArrayList
150 ArrayList<T> newList = new ArrayList();
151 // Traverse through the first list
152 for (T element : list) {
153 // If this element is not present in newList
154 // then add it
155 if (!newList.contains(element)) {
156 newList.add(element);
157 }
158 }
159 // return the new list
160 return newList;
161 //DIRECTLY COPIED//DIRECTLY COPIED//DIRECTLY COPIED//DIRECTLY COPIED//DIRECTLY COPIED//DIRECTLY COPIED
162 }
163 public static double StandardDeviation(double parseArray[]) {
164
165 double mean;
166 double sum =0.0;
167 double standardDeviation = 0.0;
168 //calculate sum of array
169 for(int i =0; i < parseArray.length; i++){
170 sum += parseArray[i];
171 }
172 //calculate mean of array
173 mean = sum/parseArray.length;
174 //calculate SD of array
175 for(int j =0; j < parseArray.length; j++){
176 standardDeviation += Math.pow(parseArray[j]-mean, 2);
177 }
178 return Math.sqrt(standardDeviation/parseArray.length);
179
180
181 }
182 public static double VarianceCalc(StartAndEndPoint parseArray[]){
183 double sum =0;
184 double temp =0;
185 double mean, variance;
186 int size = parseArray.length;
187 //Calculate sum of array
188 for(int i =0; i < parseArray.length; i++){
189 sum += parseArray[i].getP1().y;
190 }
191 //Calculate mean of array
192 mean = sum/parseArray.length;
193 //Calculate variants
194 for(int i =0; i < size; i++){
195 temp += Math.pow((parseArray[i].getP1().y-mean),2);
196 }
197 variance = Math.abs(temp/(size -1));
198 System.out.println("VARIANCE: " + variance);
199 return variance;
200 }
201 public static Boolean lineComparison(double baseLineS, double compareLineS, double compareLineE ){
202 if(baseLineS < compareLineE && baseLineS > compareLineS){
203 return true;
204 }
205 return false;
206 }
207 public static Boolean ClusterCheck(StartAndEndPoint parseArray[]){
208 try {
209 System.out.println("LENGTH: " + parseArray.length);
210 //MAKE THREE COMPARISONS
211 //After clusters have been found.
212 //Check if their x positions intersect
213 //Logic being
214 //(L1.S < L2.E && L1.S > L2.S)
215 //or
216 //(L2.S < L1.E && L2.S > L1.S)
217 //Variance is using Start of line point.
218 //USING VARIANTS
219 double variance = VarianceCalc(parseArray);
220 Boolean consistent = false;
221 if (variance <= CLUSTER_DISTANCE_MAX && variance > CLUSTER_DISTANCE_MIN) {
222 for (int i = 0; i < parseArray.length - 1; i++) {
223 System.out.println(i);
224 double l1_S = parseArray[i].getP1().x;
225 double l1_E = parseArray[i].getP2().x;
226 double l2_S = parseArray[i + 1].getP1().x;
227 double l2_E = parseArray[i + 1].getP2().x;
228
229 //Check which starts after
230 if (l1_S >= l2_S) {
231 //baseLineStart is l1_S (call with lineComparison)
232 consistent = lineComparison(l1_S, l2_S, l2_E);
233
234 } else if (l2_S > l1_S) {
235 //baseLineStart is l2_S (call with lineComparison)
236 consistent = lineComparison(l2_S, l1_S, l1_E);
237 } else {
238 System.err.println("An error, comparing l1_S and l2_S, has occurred");
239 }
240
241 //Check if false was returned;
242 if (consistent == false) {
243 System.out.println(" X positions of two lines did not overlap each other" + '\t');
244 System.out.print("l1_S: " + l1_S + '\t');
245 System.out.print("l1_E: " + l1_E + '\t');
246 System.out.print("l2_S: " + l2_S + '\t');
247 System.out.print("l2_E: " + l2_E);
248 return false;
249 }
250 }
251 //Have been through for loop, maintaining consistent being true.
252 //Have also meet the variance MIN and MAX requirement. Therefore it is a cluster
253 return true;
254 }
255 System.out.println("Did not meet Cluster Distance Min and Max requirements, Variance = " + variance);
256 return false;
257 }
258 catch (Exception e){
259 System.err.println(" "+e.getMessage());
260 return false;
261 }
262 }
263
264 //GLOBAL_CONSTANTS
265 static double CLUSTER_DISTANCE_MAX = 15;
266 static double CLUSTER_DISTANCE_MIN = 2;
267 static int CLASSIFIER_HOUGHLINESP_MIN = 10;
268 static int CLASSIFIER_HOUGHLINESP_MAX = 65;
269 static int HOUGHLINEP_THRESHOLD = 10;
270 static int STANDARD_DEVIATION_THRESHOLD = 6;
271 static int MINLINECOUNT = 40;
272 static int MAXLINEGAP = 1; //4
273 static double SLOPEGRADIENT = 0.02;
274 //SHOULD TURN INTO ARGS
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
574 private static ArrayList ClassifierLineClusterPt(ArrayList<StartAndEndPoint> linePointsArray, Mat clustersFoundRGB){
575 /*
576 ADDITION:
577 This will check for a cluster of lines that are close together.
578 1. Go through the list of Y positions(start point) in parsed array.
579 If, there is a small distance between them,
580 then, add to closeLineArray.
581
582 Have all Y positions that are close to each other now.
583 Need to find the lines that are clustered together.
584
585 Now check if there are four of these are close to each other.
586 2. Go through list of closeLine.
587 Get first four lines, traversing down a step each iteration {0,1,2,3} -> {1,2,3,4} -> {2,3,4,5}
588 If, those 4 lines are close together,
589 Then, add them to a new array that holds Line Cluster Values.
590 Go to line 4 positions down since, as do not want duplicates.
591
592 3.
593 */
594 ArrayList returnArray = new ArrayList();
595 ArrayList<StartAndEndPoint> closeLinePts = new ArrayList();
596 ArrayList<StartAndEndPoint[]> clusterPtArray = new ArrayList();
597 int clusterCount = 0;
598 try {
599 if(linePointsArray.size()> 1) {
600 /*
601 //Display input array TESTING PURPOSES
602 for (int i = 0; i < linePointsArray.size(); i++) {
603 System.out.println(linePointsArray.get(i).toString());
604 }
605 */
606 //1. Check if y points are close together
607 //go thru list and compare values against each other
608 for (int i = 0; i < linePointsArray.size(); i++){
609 //System.out.println("i: "+ linePointsArray.get(i).getP1().y);
610 for (int j = 0; j < linePointsArray.size(); j++) {
611 //System.out.println("j: "+ linePointsArray.get(j).getP1().y);
612 //Check if difference is less than 4 and the values are not duplicates.
613 if(Math.abs(linePointsArray.get(j).getP1().y - linePointsArray.get(i).getP1().y) < 5){
614 if(linePointsArray.get(j).getP1().y != linePointsArray.get(i).getP1().y){
615 closeLinePts.add(linePointsArray.get(i));
616 }
617 }
618 }
619 }
620 /*for (double num : closeLineYPos){
621 System.out.println(num);
622 } */
623
624 //2. Now check if there are four of these are close to each other.
625 //Go through all of the items in this list and check if four of them are close together
626 //Check first four items, traverse down a step {0,1,2,3} -> {1,2,3,4} -> {2,3,4,5}
627 //If 4 items are close together,
628 //Then add them to a new array that holds Line Cluster Values.
629 //Go down 4 positions down since, as do not want duplicates.
630
631 //Now have an array of at least four lines that are close together.
632 //Sort array and remove duplicates
633 Collections.sort(closeLinePts, new Comparator<StartAndEndPoint>() {
634 @Override
635 public int compare(StartAndEndPoint p1, StartAndEndPoint p2) {
636 return (int)(p1.getP1().y - p2.getP1().y);
637 }
638 });
639 closeLinePts = removeDuplicates(closeLinePts);
640 /*DISPLAYING AS EXCEPTED! WOO!
641 for (StartAndEndPoint pt : closeLinePts) {
642 System.out.println("CloseLinePTs: " + pt.getP1().y);
643 }
644 */
645
646 if(closeLinePts.size() >= 4) {
647 //FOR every item in array of CloseLines
648 for(int i= 0; i< closeLinePts.size(); i++){
649 //If last comparator is at end of array.
650 if(i + 4 >= closeLinePts.size()){
651 break;
652 }
653 else{
654 //Add 4 values of CloseLinePt Array to a tempArray
655 StartAndEndPoint[] tempPtArray = new StartAndEndPoint[4];
656 tempPtArray[0] = closeLinePts.get(i);
657 tempPtArray[1] = closeLinePts.get(i + 1);
658 tempPtArray[2] = closeLinePts.get(i + 2);
659 tempPtArray[3] = closeLinePts.get(i + 3);
660
661 //Check standard deviation between these 4 values.
662 //If it SD is less than 5 then it is considered to be a cluster of lines.
663 if(ClusterCheck(tempPtArray)){
664 //System.out.println("tempArray PT: "+tempArray[0] + " , " + tempArray[1] + " , " + tempArray[2] + " , " + tempArray[3]);
665 //System.out.println("tempArray SD: " + StandardDeviation(tempArray));
666 //Store array
667 clusterPtArray.add(tempPtArray);
668 //If I + 4 is less than the size of the array then increment by 4
669 //Go down +4 positions in closeLineYPos array
670 if((i + 4 < closeLinePts.size())){
671 //System.out.println("IF, i = " + i + " -> "+ (i+4) + ", CloseLineYpos size= " + closeLineYPos.size());
672 i = i+4;
673 }
674 else{
675 //break
676 //System.out.println("ELSE, i = " + i+ " closeLineYpos size= " + closeLineYPos.size());
677 Thread.sleep(2000);
678 break;
679 }
680 }
681 }
682 }
683 }
684 /*
685 System.out.println("Cluster Coordinates: ");
686 for(double[] items : clusterArray){
687 for(int i = 0; i <items.length; i++){
688 System.out.println("ITEMS: "+ items[i]);
689 }
690 }
691 */
692 //Setup Drawing clusters found.
693 //For every pt given the input array
694 for(StartAndEndPoint pt : linePointsArray){
695 //Go through every the Arrays in the clusterArray(clustered lines)
696 for(int i =0; i < clusterPtArray.size(); i++){
697 //Go through every item in the array
698 for(StartAndEndPoint item : clusterPtArray.get(i)) {
699 //Check if the curr item is equal to current pt
700 if (item.getP1().y == pt.getP1().y){
701 //calculate a different colour for each line
702 //Draw a line
703 Imgproc.line(clustersFoundRGB, pt.getP1(), pt.getP2(), new Scalar(0, 255, 0), 1, Imgproc.LINE_4, 0);
704 }
705 }
706 }
707
708 }
709
710 clusterCount = clusterPtArray.size();
711 //SETUP RETURN ARRAY
712 if(clusterCount >= 1){
713 returnArray.add(true);
714 returnArray.add(closeLinePts.size());
715 returnArray.add(clusterCount);
716 returnArray.add(clustersFoundRGB);
717 }
718 else{
719 returnArray.add(false);
720 returnArray.add(closeLinePts.size());
721 returnArray.add(clusterCount);
722 }
723 }
724 }
725 catch (Exception e) {
726 System.err.println(" " +e.getMessage());
727 }
728 return returnArray;
729 }
730
731
732
733 public static void main(String[] args) {
734
735 System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
736
737 try {
738 ArrayList<StartAndEndPoint> pointArrayList = new ArrayList<>();
739
740 //Variables
741 Mat edgesDetected = new Mat();
742 Mat edgesDetectedRGB = new Mat();
743 Mat clustersFoundRGB = new Mat();
744 String directory = "/Scratch/cpb16/is-sheet-music-encore/download-images/MU/";
745 //!!!!!!!!!!!!!!!!!!!!!!!!!!!NOT!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
746 //mdp.39015097852365-2.png 176 lines Contents page.
747 //mdp.39015097852555-3.png 76 lines
748 //String default_file = directory+"SheetMusic/coo.31924062612282-9.png";
749 //String default_file ="TestImages/NotNot/mdp.39015080972303-3.png";
750
751
752 //System.out.println(default_file);
753 String default_file = "TestImages/NotSheetMusic01.png";
754 //String default_file = "TestImages/NotSheetMusic02.png";
755 //String default_file = "TestImages/SheetMusic01.png";
756 //String default_file = "TestImages/SheetMusic02.png";
757 //String default_file = "TestImages/vLine.png";
758 String filename = ((args.length > 0) ? args[0] : default_file);
759 File file = new File(filename);
760 if(!file.exists()){System.err.println("Image not found: "+ filename);}
761
762 int horizontalLineCount =0;
763
764 // Load an image
765 Mat original = Imgcodecs.imread(filename, Imgcodecs.IMREAD_GRAYSCALE);
766 // Edge detection
767 Imgproc.adaptiveThreshold(original, edgesDetected,255, Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C,Imgproc.THRESH_BINARY_INV, 15, 4);
768
769 //Convert to RGB for future use
770 Imgproc.cvtColor(edgesDetected, edgesDetectedRGB, Imgproc.COLOR_GRAY2BGR);
771 clustersFoundRGB = edgesDetectedRGB.clone();
772
773 Mat linesP = new Mat(); // will hold the results of the detection
774 //(edgeDetectedImage, outputOfDetection(r,Ξ), resolution of rho, resolution of theta, threshold (minimum num of intersections)
775
776 double minLineLength = edgesDetectedRGB.size().width/8;
777
778 Imgproc.HoughLinesP(edgesDetected, linesP, 1, Math.PI / 720, HOUGHLINEP_THRESHOLD, minLineLength,MAXLINEGAP); // runs the actual detection
779 //System.out.println("Before Gradient Filtering num lines: " + linesP.rows());
780
781 // Draw the lines
782 for (int x = 0; x < linesP.rows(); x++) {
783 double[] l = linesP.get(x, 0);
784 Point p1 = new Point(l[0], l[1]);
785 Point p2 = new Point(l[2], l[3]);
786 double m = Math.abs(p2.y - p1.y)/(p2.x - p1.x);
787
788 if(m<=SLOPEGRADIENT) {
789 Imgproc.line(edgesDetectedRGB, p1, p2, new Scalar(0, 0, 255), 1, Imgproc.LINE_4, 0);
790 horizontalLineCount++;
791 pointArrayList.add(new StartAndEndPoint(p1, p2));
792 }
793
794 }
795 //Point is a co ordinate (x, y)
796 //Prove by finding number of points from one end to other:
797 //Get width of image.
798 File filenameTest = new File("TestImages/NotSheetMusic02.png");
799 BufferedImage i = ImageIO.read(filenameTest);
800 BufferedImage toBeClassifiedImg = toBufferedImage(edgesDetectedRGB);
801
802
803
804 //Display Results
805 //HighGui.imshow("Source", original);
806 //HighGui.imshow("Just Edges", justEdges); //TESTING
807 //HighGui.imshow("Detected Lines (in red) - positive", edgesDetectedRGB);
808 if(ClassifierLineClusterPt(pointArrayList, clustersFoundRGB).get(3) != null) {
809 HighGui.imshow("CLUSTERS FOUND", clustersFoundRGB);
810 }
811 //HighGui.imshow("Detected Lines (in red) - negative", edgesDetectedRGBProb);
812
813
814
815 //System.out.println("LINE COUNT RESULT: " + ClassifierLineCount(horizontalLineCount) + '\t' +"LineCount: " + horizontalLineCount); //COUNT OF LINES CLASSIFICATION
816 //System.out.println("LINE CLUSTER RESULT: " + ClassifierLineClusterOLD(toBeClassifiedImg).get(0) + '\t' + "LinesFound: " + ClassifierLineClusterOLD(toBeClassifiedImg).get(1) + '\t' + "ClustersFound: " + ClassifierLineClusterOLD(toBeClassifiedImg).get(2));
817 //System.out.println("NEW CLUSTER RESULTS: " + ClassifierLineCluster(pointArrayList,clustersFoundRGB).get(0) + '\t' + "LinesFound: " + ClassifierLineCluster(pointArrayList,clustersFoundRGB).get(1) + '\t' + "ClustersFound: " + ClassifierLineCluster(pointArrayList,clustersFoundRGB).get(2));
818 System.out.println(ClassifierLineClusterPt(pointArrayList, clustersFoundRGB));
819
820 // Wait and Exit
821 HighGui.waitKey();
822 System.exit(0);
823 }
824 catch(Exception e){
825 System.err.println(e);
826 }
827 }
828}
Note: See TracBrowser for help on using the repository browser.