Changeset 33589 for other-projects/is-sheet-music-encore/trunk/image-identification-terminal/javaClassifierComparison.java
- Timestamp:
- 2019-10-21T21:45:10+13:00 (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
other-projects/is-sheet-music-encore/trunk/image-identification-terminal/javaClassifierComparison.java
r33458 r33589 72 72 static double THRESHOLD_AREA_COUNT; 73 73 74 //******************************************************************************************** 75 //CLASSES 76 //******************************************************************************************** 77 78 //Sets globals based off properties file 79 public static void init(){ 80 try{ 81 Properties config = new Properties(); 82 FileInputStream input = new FileInputStream("configClassifierComparison.properties"); 83 config.load(input); 84 CLASSIFIER_HOUGHLINESP_MIN = Integer.parseInt(config.getProperty("CLASSIFIER_HOUGHLINESP_MIN")); 85 CLASSIFIER_HOUGHLINESP_MAX = Integer.parseInt(config.getProperty("CLASSIFIER_HOUGHLINESP_MAX")); 86 HOUGHLINEP_THRESHOLD = Integer.parseInt(config.getProperty("HOUGHLINEP_THRESHOLD")); 87 STANDARD_DEVIATION_THRESHOLD = Integer.parseInt(config.getProperty("STANDARD_DEVIATION_THRESHOLD")); 88 MINLINECOUNT = Integer.parseInt(config.getProperty("MINLINECOUNT")); 89 MAXLINEGAP = Integer.parseInt(config.getProperty("MAXLINEGAP")); 90 THRESHOLD_C = Double.parseDouble(config.getProperty("THRESHOLD_C")); 91 SLOPEGRADIENT = Double.parseDouble(config.getProperty("SLOPEGRADIENT")); 92 CLUSTER_DISTANCE_MAX = Double.parseDouble(config.getProperty("CLUSTER_DISTANCE_MAX")); 93 CLUSTER_DISTANCE_MIN = Double.parseDouble(config.getProperty("CLUSTER_DISTANCE_MIN")); 94 THRESHOLD_AREA_SIZE = Double.parseDouble(config.getProperty("THRESHOLD_AREA_SIZE")); 95 THRESHOLD_AREA_COUNT = Double.parseDouble(config.getProperty("THRESHOLD_AREA_COUNT")); 96 } 97 catch(Exception e){ 98 e.printStackTrace(); 99 } 100 } 101 74 //****************** 75 //CLASSES 76 //****************** 102 77 static public class StartAndEndPoint { 103 78 //PRIVATES … … 161 136 } 162 137 138 //****************** 139 //TRIGGERS 140 //****************** 141 /**Sets globals based off properties file*/ 142 public static void init(){ 143 try{ 144 Properties config = new Properties(); 145 FileInputStream input = new FileInputStream("configClassifierComparison.properties"); 146 config.load(input); 147 CLASSIFIER_HOUGHLINESP_MIN = Integer.parseInt(config.getProperty("CLASSIFIER_HOUGHLINESP_MIN")); 148 CLASSIFIER_HOUGHLINESP_MAX = Integer.parseInt(config.getProperty("CLASSIFIER_HOUGHLINESP_MAX")); 149 HOUGHLINEP_THRESHOLD = Integer.parseInt(config.getProperty("HOUGHLINEP_THRESHOLD")); 150 STANDARD_DEVIATION_THRESHOLD = Integer.parseInt(config.getProperty("STANDARD_DEVIATION_THRESHOLD")); 151 MINLINECOUNT = Integer.parseInt(config.getProperty("MINLINECOUNT")); 152 MAXLINEGAP = Integer.parseInt(config.getProperty("MAXLINEGAP")); 153 THRESHOLD_C = Double.parseDouble(config.getProperty("THRESHOLD_C")); 154 SLOPEGRADIENT = Double.parseDouble(config.getProperty("SLOPEGRADIENT")); 155 CLUSTER_DISTANCE_MAX = Double.parseDouble(config.getProperty("CLUSTER_DISTANCE_MAX")); 156 CLUSTER_DISTANCE_MIN = Double.parseDouble(config.getProperty("CLUSTER_DISTANCE_MIN")); 157 THRESHOLD_AREA_SIZE = Double.parseDouble(config.getProperty("THRESHOLD_AREA_SIZE")); 158 THRESHOLD_AREA_COUNT = Double.parseDouble(config.getProperty("THRESHOLD_AREA_COUNT")); 159 } 160 catch(Exception e){ 161 e.printStackTrace(); 162 } 163 } 164 /***/ 163 165 public static void main(String[] args) { 164 166 init(); 165 167 try { 166 168 167 if (args.length !=3) {169 if (args.length < 3) { 168 170 System.out.println("Usage: imageClassifier <inputFilename> <classifierType> <outputFilename>"); 171 System.out.println("+ (Optional)<BorderIgnoreAmount[0,5, 10, 20, 40]>"); 169 172 } else { 170 173 Pair algorithmResult = new Pair(); 171 172 174 Boolean result = null; 173 175 String result_cluster = ""; … … 176 178 String outputFilename = args[2]; 177 179 Boolean enableLineClustering = null; 180 178 181 //Prep Writing output to disc 179 182 File log = new File(outputFilename); 180 183 FileWriter fileWriter = new FileWriter(log, true); 181 184 BufferedWriter bw = new BufferedWriter(fileWriter); 182 //Execute classifierType defined from arguement183 184 185 File imgCheck = new File(imageFilename); 185 186 if(!imgCheck.exists()){System.err.println("Image not found: "+ imageFilename);} 186 187 187 //Split output by tab for processing in next java program 188 //imageFilename = 1, result = 3, classifierType = 4 189 188 // 189 190 191 //Arguement Preps 192 int borderIgnoreAmount; 193 if(args.length >= 4){borderIgnoreAmount =Integer.parseInt(args[3]);} 194 else {borderIgnoreAmount=-1;} 195 196 //imageFilename = 1, result = 3, classifierType = 4 ????? 190 197 switch (classifierType) { 198 //Splits output by tab for processing in next java program 191 199 case "count": 192 200 enableLineClustering = false; 193 algorithmResult = Algorithm_HoughLinesP_Single(imageFilename, enableLineClustering );201 algorithmResult = Algorithm_HoughLinesP_Single(imageFilename, enableLineClustering, borderIgnoreAmount); 194 202 bw.write("Filename:" + '\t' + imageFilename + '\t' + "Classified as:" + '\t' + algorithmResult.getBoolean() + '\t' + "Number of lines:" + '\t' + algorithmResult.getInteger() + '\t' + classifierType + '\n'); 195 203 break; 196 204 case "cluster": 197 205 enableLineClustering = true; 198 algorithmResult = Algorithm_HoughLinesP_Single(imageFilename, enableLineClustering );206 algorithmResult = Algorithm_HoughLinesP_Single(imageFilename, enableLineClustering, borderIgnoreAmount); 199 207 bw.write("Filename:" + '\t' + imageFilename + '\t' + "Classified as:" + '\t' + algorithmResult.getBoolean() + '\t' + "Number of lines:" + '\t' + algorithmResult.getInteger() + '\t' + classifierType + '\n'); 200 208 break; 201 209 case "combo": 202 algorithmResult = Algorithm_HoughLinesP_Combo(imageFilename );210 algorithmResult = Algorithm_HoughLinesP_Combo(imageFilename, borderIgnoreAmount); 203 211 bw.write("Filename:" + '\t' + imageFilename + '\t' + "Classified as:" + '\t' + algorithmResult.getBoolean() + '\t' + "Number of lines:" + '\t' + algorithmResult.getInteger() + '\t' + classifierType + '\n'); 204 212 break; 205 213 case "morphology": 206 algorithmResult = Algorithm_Morphology(imageFilename );214 algorithmResult = Algorithm_Morphology(imageFilename, borderIgnoreAmount); 207 215 bw.write("Filename:" + '\t' + imageFilename + '\t' + "Classified as:" + '\t' + algorithmResult.getBoolean() + '\t' + "Number of areas:" + '\t' + algorithmResult.getInteger() + '\t' + classifierType + '\n'); 208 216 break; … … 210 218 System.out.println("unknown algorithm"); 211 219 break; 212 } 213 220 } 214 221 bw.close(); 215 222 } … … 222 229 //ALGORITHM FUNCTIONS 223 230 //****************** 224 private static Pair Algorithm_HoughLinesP_Single(String filename, Boolean enableLineClusterDetection){ 231 private static Pair Algorithm_HoughLinesP_Single(String filename, Boolean enableLineClusterDetection, int borderIgnoreAmount){ 232 //****************EXPLANATION************************************************** 233 // 234 //Load an image in greyscale 235 //Additional matrix to hold results of line detection 236 //Inversed Binarization of image 237 //Detect lines in image 238 //Go thru every line detected and check its gradient is less than SLOPEGRADIENT 239 // 240 //****************EXPLANATION************************************************** 225 241 System.loadLibrary(Core.NATIVE_LIBRARY_NAME); 226 242 Boolean isSheetMusic = null; … … 235 251 ArrayList<StartAndEndPoint> pointArrayList = new ArrayList<StartAndEndPoint>(); 236 252 237 //****************EXPLANATION**************************************************238 //239 //Load an image in greyscale240 //Additional matrix to hold results of line detection241 //Inversed Binarization of image242 //Detect lines in image243 //Go thru every line detected and check its gradient is less than SLOPEGRADIENT244 //245 //****************EXPLANATION**************************************************246 247 253 Mat original = Imgcodecs.imread(filename, Imgcodecs.IMREAD_GRAYSCALE); 254 255 Mat binarized = original.clone(); 256 int blockSize = binarized.height()/3; 257 //BlockSize must be blockSize % 2 == 1 && blockSize > 1 258 while (!(blockSize % 2 == 1 && blockSize > 1)) { 259 blockSize++; 260 } 261 262 263 System.out.println("Width: " + binarized.width() + " Height: " + binarized.height()); 264 //************************ 265 //Argument Setup 266 //************************ 267 double divisor; 268 switch (borderIgnoreAmount){ 269 case 5: 270 divisor = 40; 271 break; 272 case 10: 273 divisor = 20; 274 break; 275 case 20: 276 divisor = 10; 277 break; 278 case 40: 279 divisor = 5; 280 break; 281 case -1: 282 divisor = -1; 283 break; 284 default: divisor = -1; 285 } 286 if(divisor != -1 ) { 287 Mat mid = new Mat(); 288 Imgproc.adaptiveThreshold(original, mid,255, Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C,Imgproc.THRESH_BINARY_INV, blockSize, THRESHOLD_C); 289 //Remove borders from Mat 290 //Get width and 291 double maxX = mid.size().width; 292 double maxY = mid.size().height; 293 Point cp1 = new Point(maxX / divisor, maxY / divisor); 294 Point cp2 = new Point(maxX - cp1.x, maxY - cp1.y); 295 Rect rectCrop = new Rect(cp1, cp2); 296 binarized = mid.submat(rectCrop); 297 } 298 else{Imgproc.adaptiveThreshold(original, binarized,255, Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C,Imgproc.THRESH_BINARY_INV, blockSize, THRESHOLD_C);} 299 System.out.println("Width: " + binarized.width() + " Height: " + binarized.height()); 300 edgesDetected = binarized.clone(); 301 302 248 303 Mat linesP = new Mat(); //will hold the results of the detection 249 Imgproc.adaptiveThreshold(original, edgesDetected,255, Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C,Imgproc.THRESH_BINARY_INV,15, THRESHOLD_C);250 304 double minLineLength = edgesDetected.size().width/8; 251 305 Imgproc.HoughLinesP(edgesDetected, linesP, 1, Math.PI / 720, HOUGHLINEP_THRESHOLD, minLineLength, MAXLINEGAP); … … 274 328 return returnVariables; 275 329 } 276 private static Pair Algorithm_HoughLinesP_Combo(String filename){ 330 private static Pair Algorithm_HoughLinesP_Combo(String filename, int borderIgnoreAmount){ 331 //****************EXPLANATION************************************************** 332 // 333 //Load an image in greyscale 334 //Additional matrix to hold results of line detection 335 //Inversed Binarization of image 336 //Detect lines in image 337 //Go thru every line detected and check its gradient is less than SLOPEGRADIENT 338 // 339 //****************EXPLANATION************************************************** 340 277 341 System.loadLibrary(Core.NATIVE_LIBRARY_NAME); 278 342 Boolean isSheetMusic = null; … … 281 345 //Variables 282 346 int horizontalLineCount =0; 347 283 348 Mat edgesDetected = new Mat(); 284 349 Mat edgesDetectedRGB = new Mat(); … … 286 351 Mat edgesDetectedRGBProb; 287 352 ArrayList<StartAndEndPoint> pointArrayList = new ArrayList<StartAndEndPoint>(); 288 289 //****************EXPLANATION**************************************************290 //291 //Load an image in greyscale292 //Additional matrix to hold results of line detection293 //Inversed Binarization of image294 //Detect lines in image295 //Go thru every line detected and check its gradient is less than SLOPEGRADIENT296 //297 //****************EXPLANATION**************************************************298 299 353 Mat original = Imgcodecs.imread(filename, Imgcodecs.IMREAD_GRAYSCALE); 354 355 Mat binarized = original.clone(); 356 int blockSize = binarized.height()/3; 357 while (!(blockSize % 2 == 1 && blockSize > 1)) { 358 blockSize++; 359 } 360 System.out.println("Width: " + binarized.width() + " Height: " + binarized.height()); 361 //************************ 362 //Argument Setup 363 //************************ 364 double divisor; 365 switch (borderIgnoreAmount){ 366 case 5: 367 divisor = 40; 368 break; 369 case 10: 370 divisor = 20; 371 break; 372 case 20: 373 divisor = 10; 374 break; 375 case 40: 376 divisor = 5; 377 break; 378 case -1: 379 divisor = -1; 380 break; 381 default: divisor = -1; 382 } 383 if(divisor != -1 ) { 384 Mat mid = new Mat(); 385 Imgproc.adaptiveThreshold(original, mid,255, Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C,Imgproc.THRESH_BINARY_INV, blockSize, THRESHOLD_C); 386 //Remove borders from Mat 387 //Get width and 388 double maxX = mid.size().width; 389 double maxY = mid.size().height; 390 Point cp1 = new Point(maxX / divisor, maxY / divisor); 391 Point cp2 = new Point(maxX - cp1.x, maxY - cp1.y); 392 Rect rectCrop = new Rect(cp1, cp2); 393 binarized = mid.submat(rectCrop); 394 } 395 else{Imgproc.adaptiveThreshold(original, binarized,255, Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C,Imgproc.THRESH_BINARY_INV, blockSize, THRESHOLD_C);} 396 System.out.println("Width: " + binarized.width() + " Height: " + binarized.height()); 397 edgesDetected = binarized.clone(); 398 300 399 Mat linesP = new Mat(); //will hold the results of the detection 301 Imgproc.adaptiveThreshold(original, edgesDetected,255, Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C,Imgproc.THRESH_BINARY_INV,15, THRESHOLD_C);302 400 double minLineLength = edgesDetected.size().width/8; 303 401 Imgproc.HoughLinesP(edgesDetected, linesP, 1, Math.PI / 720, HOUGHLINEP_THRESHOLD, minLineLength, MAXLINEGAP); … … 320 418 } 321 419 else if (isSheetMusic == false){ 420 System.out.println("TEST"); 322 421 returnVariables = Classifier_ClusterDetection(pointArrayList); 323 422 } … … 328 427 return returnVariables; 329 428 } 330 private static Pair Algorithm_MorphologyOLD2(String filename){ 331 429 private static Pair Algorithm_Morphology(String filename, int borderIgnoreAmount){ 332 430 System.loadLibrary(Core.NATIVE_LIBRARY_NAME); 333 Boolean isSheetMusic = null;334 431 Pair returnVariables = new Pair(); 335 432 int areaCounter = 0; 336 try{337 Mat edgesDetectedRGB = new Mat();338 Mat original = Imgcodecs.imread(filename, Imgcodecs.IMREAD_GRAYSCALE);339 340 System.out.println("Width: " + original.width() + " Height: " + original.height());341 342 ArrayList<MatOfPoint> contours = new ArrayList<MatOfPoint>();343 Mat hierarchy = new Mat();344 345 //Thresholds346 Imgproc.adaptiveThreshold(original, original,255, Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C,Imgproc.THRESH_BINARY_INV, 15, THRESHOLD_C);347 Mat processed = original.clone();348 //Morphological Processing349 Mat kernelErode = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(10,1));350 Imgproc.erode(processed,processed,kernelErode);351 352 Mat kernelDilate = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(20,3));353 Imgproc.dilate(processed,processed,kernelDilate);354 355 Mat kernelOpening = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(4,4));356 Imgproc.morphologyEx(processed, processed, Imgproc.MORPH_CLOSE, kernelOpening);357 358 Mat kernelErode02 = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(8,8));359 Imgproc.erode(processed,processed,kernelErode02);360 361 //Detect contours362 Imgproc.findContours(processed, contours, hierarchy, Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE);363 364 //Record areas365 for (int i = 0; i < contours.size(); i++) {366 double area = Imgproc.contourArea(contours.get(i));367 System.out.println("AREA: " + area);368 //Check if area detected meets threshold369 if(area > THRESHOLD_AREA_SIZE) {370 areaCounter++;371 372 }373 }374 System.out.println("areacount = " + areaCounter);375 376 //Calculates if sheet music or not377 if(areaCounter >= THRESHOLD_AREA_COUNT){378 isSheetMusic = true;379 returnVariables.setBoolean(isSheetMusic);380 returnVariables.setInteger(areaCounter);381 }382 }383 catch(Exception e){384 System.err.println(e);385 }386 return returnVariables;387 }388 private static Pair Algorithm_MorphologyOLD(String filename){389 390 System.loadLibrary(Core.NATIVE_LIBRARY_NAME);391 Boolean isSheetMusic = null;392 Pair returnVariables = new Pair();393 int FILLED = -1;394 try{395 Mat original1 = Imgcodecs.imread(filename, Imgcodecs.IMREAD_GRAYSCALE);396 System.out.println("Width: " + original1.width() + " Height: " + original1.height());397 Mat original = original1.clone();398 Imgproc.adaptiveThreshold(original1, original,255, Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C,Imgproc.THRESH_BINARY_INV, 15, THRESHOLD_C);399 Mat test = original.clone();400 //************************************401 //Large Object Removal402 //************************************403 Mat srcLOR = original.clone();404 Mat maskLOR = new Mat();405 Mat dstLOR = new Mat();406 407 //denoize408 Mat denoize = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(5,5));409 Imgproc.morphologyEx(srcLOR,maskLOR, Imgproc.MORPH_OPEN, denoize);410 411 //close up gaps412 Mat gapCloser = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(5,5));413 Imgproc.morphologyEx(maskLOR,maskLOR,Imgproc.MORPH_CLOSE, gapCloser);414 415 //Isolate large items416 Mat isolateLarge = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(8, 8));417 Imgproc.morphologyEx(maskLOR,maskLOR,Imgproc.MORPH_OPEN, isolateLarge);418 419 //Remove large items from image420 Core.bitwise_not(maskLOR,maskLOR);421 srcLOR.copyTo(dstLOR, maskLOR);422 423 //****************************************424 //Small object removal (SOR)425 //****************************************426 427 Mat srcSOR = dstLOR.clone();428 Mat maskSOR = new Mat();429 Mat dstSOR = new Mat();430 431 Mat startSOR =Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(7,7));432 Imgproc.morphologyEx(srcSOR,maskSOR, Imgproc.MORPH_OPEN, startSOR);433 434 Mat highlightSmall = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(7,7));435 Imgproc.dilate(maskSOR, maskSOR, highlightSmall);436 437 438 /* Mat isolateSmall =Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(10,10));439 Imgproc.morphologyEx(maskSOR,maskSOR,Imgproc.MORPH_CLOSE, isolateSmall);440 imageViewer("13 isolate small - mask", maskSOR);441 */442 443 //Remove small items from image444 Core.bitwise_not(maskSOR, maskSOR);445 srcSOR.copyTo(dstSOR, maskSOR);446 447 448 //****************************************449 //start staff line detection450 //****************************************451 452 Mat kernelErode = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(15,2)); //10,2453 Imgproc.erode(dstSOR,test,kernelErode);454 455 456 Mat kernelDilate = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(10,4)); //20,3457 Imgproc.dilate(test,test,kernelDilate);458 459 460 Mat kernelClose = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(10,4)); //4,4461 Imgproc.morphologyEx(test, test, Imgproc.MORPH_CLOSE, kernelClose);462 463 464 465 Mat kernelErode02 = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(10,4)); //10,1466 Imgproc.erode(test,test,kernelErode02);467 468 469 //********************************************************************************470 //DETECT OUTLINE AND FIND AREA OF THESE LINES.471 //********************************************************************************472 ArrayList<MatOfPoint> contours = new ArrayList<MatOfPoint>();473 ArrayList<MatOfPoint> largeContours = new ArrayList<MatOfPoint>();474 ArrayList<MatOfPoint> postContours = new ArrayList<MatOfPoint>();475 Mat hierarchy = new Mat();476 477 //PARAMETERS: input image, output array of arrays, output array, contour retrieval mode, contour approximation method.478 //(contours) output array of arrays: Detected contours. Each contour is stored as a vector of points479 //(hierarchy) output array: Optional output vector, containing information about the image topology.480 //https://docs.opencv.org/3.3.1/d3/dc0/group__imgproc__shape.html#ga17ed9f5d79ae97bd4c7cf18403e1689a481 482 Imgproc.findContours(test, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);483 484 System.out.println(contours.size());485 //Draw contours and record areas486 Mat allContoursFound = Mat.zeros(test.size(), CvType.CV_8UC3);487 Mat largeContoursFound = allContoursFound.clone() ;488 Mat postContoursFound = allContoursFound.clone();489 int areaCounter = 0;490 491 //Have created a preprocess to remove large objects.492 //Need to now finalized Classifier, re try area detection.493 //Paths to take - rectangle boxes around detected contours over threshold (area or perimeter)494 //Just use area and periemter to determine if sheet music495 //Discuss with david before weekend perhaps?496 497 Imgproc.drawContours(allContoursFound, contours, -1, new Scalar(0, 255, 0), 1); //USES LINE_8498 for (int i = 0; i < contours.size(); i++) {499 double area = Imgproc.contourArea(contours.get(i));500 if(area > 100) {501 //System.out.println("AREA: " + area);502 Imgproc.drawContours(largeContoursFound, contours, i, new Scalar(255, 0, 0), FILLED);503 //create list of large coutours found504 largeContours.add(contours.get(i));505 }506 }507 508 //*****************************************************************509 //Circles and centres on processed images510 //*****************************************************************511 512 //Init arrays513 Mat circleOutput = allContoursFound.clone();514 MatOfPoint2f[] contoursPoly = new MatOfPoint2f[largeContours.size()];515 Point[] centers = new Point[largeContours.size()];516 float[][] radius = new float[largeContours.size()][1];517 518 //Fill arrays519 for (int i = 0; i < largeContours.size(); i++) {520 contoursPoly[i] = new MatOfPoint2f();521 Imgproc.approxPolyDP(new MatOfPoint2f(largeContours.get(i).toArray()), contoursPoly[i], 1, true);522 centers[i] = new Point();523 Imgproc.minEnclosingCircle(contoursPoly[i], centers[i], radius[i]);524 525 }526 //Draw circle for each large contour527 for (int i = 0; i < largeContours.size(); i++) {528 Imgproc.circle(circleOutput, centers[i], (int) radius[i][0],new Scalar(255, 0, 0), 1);529 }530 531 532 //********************************************************************************533 //Centroids - Everything must be to scale534 //********************************************************************************535 536 ArrayList<Moments> mu = new ArrayList<Moments>(largeContours.size());537 Mat centreOutput = Mat.zeros(largeContoursFound.size(), CvType.CV_8UC3);538 for (int i = 0; i < largeContours.size(); i++) {539 mu.add(i, Imgproc.moments(largeContours.get(i), false));540 Moments p = mu.get(i);541 int x = (int) (p.get_m10() / p.get_m00());542 int y = (int) (p.get_m01() / p.get_m00());543 Imgproc.circle(centreOutput, new Point(x, y), 4, new Scalar(255, 255, 255), 30);544 }545 546 //***********************************************547 //PostProcessing - Morphology Classifier548 // Use dilation to "Connect the dots"549 // Testing showed the centroids were clustered together550 // Then use area or perimeter as a classifier filter551 //***********************************************552 553 Mat postDilate = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(150,15));554 Imgproc.dilate(centreOutput,centreOutput,postDilate);555 556 Mat postClose = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(10,4)); //4,4557 Imgproc.morphologyEx(centreOutput, centreOutput, Imgproc.MORPH_CLOSE, postClose);558 559 Mat postDenoize = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(100,100));560 Imgproc.morphologyEx(centreOutput,centreOutput, Imgproc.MORPH_OPEN, postDenoize);561 562 //Find area563 Mat centreOutputGrey = new Mat();564 Imgproc.cvtColor(centreOutput, centreOutputGrey, Imgproc.COLOR_RGB2GRAY);565 Imgproc.findContours(centreOutputGrey, postContours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);566 567 for (int i = 0; i < postContours.size(); i++) {568 double area = Imgproc.contourArea(postContours.get(i));569 if(area > THRESHOLD_AREA_SIZE) {570 //System.err.println("POST AREA: " + area);571 Imgproc.drawContours(postContoursFound, postContours, i, new Scalar(0, 255, 0), FILLED);572 areaCounter++;573 }574 }575 //Classifier Calculation576 if(areaCounter >= THRESHOLD_AREA_COUNT){577 returnVariables.setBoolean(true);578 returnVariables.setInteger(areaCounter);579 }580 }581 catch(Exception e){582 System.err.println(e);583 }584 return returnVariables;585 }586 private static Pair Algorithm_Morphology(String filename){587 System.loadLibrary(Core.NATIVE_LIBRARY_NAME);588 Pair returnVariables = new Pair();589 int areaCounter=0;590 433 Mat original = Imgcodecs.imread(filename, Imgcodecs.IMREAD_GRAYSCALE); 591 Mat binarizedOriginal = original.clone(); 592 Imgproc.adaptiveThreshold(original, binarizedOriginal,255, Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C,Imgproc.THRESH_BINARY_INV, 15, THRESHOLD_C); 434 Mat binarized = original.clone(); 435 int blockSize = binarized.height()/3; 436 while (!(blockSize % 2 == 1 && blockSize > 1)) { 437 blockSize++; 438 } 439 System.out.println("Width: " + binarized.width() + " Height: " + binarized.height()); 440 //************************ 441 //Argument Setup 442 //************************ 443 double divisor; 444 switch (borderIgnoreAmount){ 445 case 5: 446 divisor = 40; 447 break; 448 case 10: 449 divisor = 20; 450 break; 451 case 20: 452 divisor = 10; 453 break; 454 case 40: 455 divisor = 5; 456 break; 457 case -1: 458 divisor = -1; 459 break; 460 default: divisor = -1; 461 } 462 if(divisor != -1 ) { 463 Mat mid = new Mat(); 464 Imgproc.adaptiveThreshold(original, mid,255, Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C,Imgproc.THRESH_BINARY_INV, blockSize, THRESHOLD_C); 465 //Remove borders from Mat 466 //Get width and 467 double maxX = mid.size().width; 468 double maxY = mid.size().height; 469 Point cp1 = new Point(maxX / divisor, maxY / divisor); 470 Point cp2 = new Point(maxX - cp1.x, maxY - cp1.y); 471 Rect rectCrop = new Rect(cp1, cp2); 472 binarized = mid.submat(rectCrop); 473 } 474 else{Imgproc.adaptiveThreshold(original, binarized,255, Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C,Imgproc.THRESH_BINARY_INV, blockSize, THRESHOLD_C);} 475 System.out.println("Width: " + binarized.width() + " Height: " + binarized.height()); 593 476 try{ 594 477 //************************************ 595 478 //1. Large Object Remover 596 479 //************************************ 597 Mat srcLOR = binarized Original.clone();480 Mat srcLOR = binarized.clone(); 598 481 Mat maskLOR = new Mat(); 599 482 Mat dstLOR = new Mat(); … … 614 497 srcLOR.copyTo(dstLOR, maskLOR); 615 498 616 Mat base = binarized Original.clone();499 Mat base = binarized.clone(); 617 500 //*********************************** 618 501 //3. Isolate straight lines … … 872 755 } 873 756 } 757 758 //****************** 759 //OLD FUNCTIONS 760 //****************** 761 private static Pair Algorithm_MorphologyOLD2(String filename){ 762 763 System.loadLibrary(Core.NATIVE_LIBRARY_NAME); 764 Boolean isSheetMusic = null; 765 Pair returnVariables = new Pair(); 766 int areaCounter = 0; 767 try{ 768 Mat edgesDetectedRGB = new Mat(); 769 Mat original = Imgcodecs.imread(filename, Imgcodecs.IMREAD_GRAYSCALE); 770 771 System.out.println("Width: " + original.width() + " Height: " + original.height()); 772 773 ArrayList<MatOfPoint> contours = new ArrayList<MatOfPoint>(); 774 Mat hierarchy = new Mat(); 775 776 //Thresholds 777 Imgproc.adaptiveThreshold(original, original,255, Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C,Imgproc.THRESH_BINARY_INV, 15, THRESHOLD_C); 778 Mat processed = original.clone(); 779 //Morphological Processing 780 Mat kernelErode = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(10,1)); 781 Imgproc.erode(processed,processed,kernelErode); 782 783 Mat kernelDilate = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(20,3)); 784 Imgproc.dilate(processed,processed,kernelDilate); 785 786 Mat kernelOpening = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(4,4)); 787 Imgproc.morphologyEx(processed, processed, Imgproc.MORPH_CLOSE, kernelOpening); 788 789 Mat kernelErode02 = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(8,8)); 790 Imgproc.erode(processed,processed,kernelErode02); 791 792 //Detect contours 793 Imgproc.findContours(processed, contours, hierarchy, Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE); 794 795 //Record areas 796 for (int i = 0; i < contours.size(); i++) { 797 double area = Imgproc.contourArea(contours.get(i)); 798 System.out.println("AREA: " + area); 799 //Check if area detected meets threshold 800 if(area > THRESHOLD_AREA_SIZE) { 801 areaCounter++; 802 803 } 804 } 805 System.out.println("areacount = " + areaCounter); 806 807 //Calculates if sheet music or not 808 if(areaCounter >= THRESHOLD_AREA_COUNT){ 809 isSheetMusic = true; 810 returnVariables.setBoolean(isSheetMusic); 811 returnVariables.setInteger(areaCounter); 812 } 813 } 814 catch(Exception e){ 815 System.err.println(e); 816 } 817 return returnVariables; 818 } 819 private static Pair Algorithm_MorphologyOLD(String filename){ 820 821 System.loadLibrary(Core.NATIVE_LIBRARY_NAME); 822 Boolean isSheetMusic = null; 823 Pair returnVariables = new Pair(); 824 int FILLED = -1; 825 try{ 826 Mat original1 = Imgcodecs.imread(filename, Imgcodecs.IMREAD_GRAYSCALE); 827 System.out.println("Width: " + original1.width() + " Height: " + original1.height()); 828 Mat original = original1.clone(); 829 Imgproc.adaptiveThreshold(original1, original,255, Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C,Imgproc.THRESH_BINARY_INV, 15, THRESHOLD_C); 830 Mat test = original.clone(); 831 //************************************ 832 //Large Object Removal 833 //************************************ 834 Mat srcLOR = original.clone(); 835 Mat maskLOR = new Mat(); 836 Mat dstLOR = new Mat(); 837 838 //denoize 839 Mat denoize = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(5,5)); 840 Imgproc.morphologyEx(srcLOR,maskLOR, Imgproc.MORPH_OPEN, denoize); 841 842 //close up gaps 843 Mat gapCloser = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(5,5)); 844 Imgproc.morphologyEx(maskLOR,maskLOR,Imgproc.MORPH_CLOSE, gapCloser); 845 846 //Isolate large items 847 Mat isolateLarge = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(8, 8)); 848 Imgproc.morphologyEx(maskLOR,maskLOR,Imgproc.MORPH_OPEN, isolateLarge); 849 850 //Remove large items from image 851 Core.bitwise_not(maskLOR,maskLOR); 852 srcLOR.copyTo(dstLOR, maskLOR); 853 854 //**************************************** 855 //Small object removal (SOR) 856 //**************************************** 857 858 Mat srcSOR = dstLOR.clone(); 859 Mat maskSOR = new Mat(); 860 Mat dstSOR = new Mat(); 861 862 Mat startSOR =Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(7,7)); 863 Imgproc.morphologyEx(srcSOR,maskSOR, Imgproc.MORPH_OPEN, startSOR); 864 865 Mat highlightSmall = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(7,7)); 866 Imgproc.dilate(maskSOR, maskSOR, highlightSmall); 867 868 869 /* Mat isolateSmall =Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(10,10)); 870 Imgproc.morphologyEx(maskSOR,maskSOR,Imgproc.MORPH_CLOSE, isolateSmall); 871 imageViewer("13 isolate small - mask", maskSOR); 872 */ 873 874 //Remove small items from image 875 Core.bitwise_not(maskSOR, maskSOR); 876 srcSOR.copyTo(dstSOR, maskSOR); 877 878 879 //**************************************** 880 //start staff line detection 881 //**************************************** 882 883 Mat kernelErode = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(15,2)); //10,2 884 Imgproc.erode(dstSOR,test,kernelErode); 885 886 887 Mat kernelDilate = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(10,4)); //20,3 888 Imgproc.dilate(test,test,kernelDilate); 889 890 891 Mat kernelClose = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(10,4)); //4,4 892 Imgproc.morphologyEx(test, test, Imgproc.MORPH_CLOSE, kernelClose); 893 894 895 896 Mat kernelErode02 = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(10,4)); //10,1 897 Imgproc.erode(test,test,kernelErode02); 898 899 900 //******************************************************************************** 901 //DETECT OUTLINE AND FIND AREA OF THESE LINES. 902 //******************************************************************************** 903 ArrayList<MatOfPoint> contours = new ArrayList<MatOfPoint>(); 904 ArrayList<MatOfPoint> largeContours = new ArrayList<MatOfPoint>(); 905 ArrayList<MatOfPoint> postContours = new ArrayList<MatOfPoint>(); 906 Mat hierarchy = new Mat(); 907 908 //PARAMETERS: input image, output array of arrays, output array, contour retrieval mode, contour approximation method. 909 //(contours) output array of arrays: Detected contours. Each contour is stored as a vector of points 910 //(hierarchy) output array: Optional output vector, containing information about the image topology. 911 //https://docs.opencv.org/3.3.1/d3/dc0/group__imgproc__shape.html#ga17ed9f5d79ae97bd4c7cf18403e1689a 912 913 Imgproc.findContours(test, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE); 914 915 System.out.println(contours.size()); 916 //Draw contours and record areas 917 Mat allContoursFound = Mat.zeros(test.size(), CvType.CV_8UC3); 918 Mat largeContoursFound = allContoursFound.clone() ; 919 Mat postContoursFound = allContoursFound.clone(); 920 int areaCounter = 0; 921 922 //Have created a preprocess to remove large objects. 923 //Need to now finalized Classifier, re try area detection. 924 //Paths to take - rectangle boxes around detected contours over threshold (area or perimeter) 925 //Just use area and periemter to determine if sheet music 926 //Discuss with david before weekend perhaps? 927 928 Imgproc.drawContours(allContoursFound, contours, -1, new Scalar(0, 255, 0), 1); //USES LINE_8 929 for (int i = 0; i < contours.size(); i++) { 930 double area = Imgproc.contourArea(contours.get(i)); 931 if(area > 100) { 932 //System.out.println("AREA: " + area); 933 Imgproc.drawContours(largeContoursFound, contours, i, new Scalar(255, 0, 0), FILLED); 934 //create list of large coutours found 935 largeContours.add(contours.get(i)); 936 } 937 } 938 939 //***************************************************************** 940 //Circles and centres on processed images 941 //***************************************************************** 942 943 //Init arrays 944 Mat circleOutput = allContoursFound.clone(); 945 MatOfPoint2f[] contoursPoly = new MatOfPoint2f[largeContours.size()]; 946 Point[] centers = new Point[largeContours.size()]; 947 float[][] radius = new float[largeContours.size()][1]; 948 949 //Fill arrays 950 for (int i = 0; i < largeContours.size(); i++) { 951 contoursPoly[i] = new MatOfPoint2f(); 952 Imgproc.approxPolyDP(new MatOfPoint2f(largeContours.get(i).toArray()), contoursPoly[i], 1, true); 953 centers[i] = new Point(); 954 Imgproc.minEnclosingCircle(contoursPoly[i], centers[i], radius[i]); 955 956 } 957 //Draw circle for each large contour 958 for (int i = 0; i < largeContours.size(); i++) { 959 Imgproc.circle(circleOutput, centers[i], (int) radius[i][0],new Scalar(255, 0, 0), 1); 960 } 961 962 963 //******************************************************************************** 964 //Centroids - Everything must be to scale 965 //******************************************************************************** 966 967 ArrayList<Moments> mu = new ArrayList<Moments>(largeContours.size()); 968 Mat centreOutput = Mat.zeros(largeContoursFound.size(), CvType.CV_8UC3); 969 for (int i = 0; i < largeContours.size(); i++) { 970 mu.add(i, Imgproc.moments(largeContours.get(i), false)); 971 Moments p = mu.get(i); 972 int x = (int) (p.get_m10() / p.get_m00()); 973 int y = (int) (p.get_m01() / p.get_m00()); 974 Imgproc.circle(centreOutput, new Point(x, y), 4, new Scalar(255, 255, 255), 30); 975 } 976 977 //*********************************************** 978 //PostProcessing - Morphology Classifier 979 // Use dilation to "Connect the dots" 980 // Testing showed the centroids were clustered together 981 // Then use area or perimeter as a classifier filter 982 //*********************************************** 983 984 Mat postDilate = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(150,15)); 985 Imgproc.dilate(centreOutput,centreOutput,postDilate); 986 987 Mat postClose = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(10,4)); //4,4 988 Imgproc.morphologyEx(centreOutput, centreOutput, Imgproc.MORPH_CLOSE, postClose); 989 990 Mat postDenoize = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(100,100)); 991 Imgproc.morphologyEx(centreOutput,centreOutput, Imgproc.MORPH_OPEN, postDenoize); 992 993 //Find area 994 Mat centreOutputGrey = new Mat(); 995 Imgproc.cvtColor(centreOutput, centreOutputGrey, Imgproc.COLOR_RGB2GRAY); 996 Imgproc.findContours(centreOutputGrey, postContours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE); 997 998 for (int i = 0; i < postContours.size(); i++) { 999 double area = Imgproc.contourArea(postContours.get(i)); 1000 if(area > THRESHOLD_AREA_SIZE) { 1001 //System.err.println("POST AREA: " + area); 1002 Imgproc.drawContours(postContoursFound, postContours, i, new Scalar(0, 255, 0), FILLED); 1003 areaCounter++; 1004 } 1005 } 1006 //Classifier Calculation 1007 if(areaCounter >= THRESHOLD_AREA_COUNT){ 1008 returnVariables.setBoolean(true); 1009 returnVariables.setInteger(areaCounter); 1010 } 1011 } 1012 catch(Exception e){ 1013 System.err.println(e); 1014 } 1015 return returnVariables; 1016 } 874 1017 }
Note:
See TracChangeset
for help on using the changeset viewer.