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

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

made progress with morphology. Need to have a better area dimension threshold setup

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