/* StartAndEndPoint l1 = parseArray[i]; StartAndEndPoint l2 = parseArray[i+ 1]; //CHECK WHICH line starts after the other //If l1 is starting after, then comparisons are based around l1.s //System.out.println("l1: " + l1.getP1().x); //System.out.println("l2: " + l2.getP1().x); System.out.println("1.0: L1S: " + l1.getP1().x + " larger than L2S: " + l2.getP1().x); if(l1.getP1().x > l2.getP1().x) { System.out.println("1.1: Comparing L1S: " + l1.getP1().x + " less than L2E: " + l2.getP2().x); if (l1.getP1().x < l2.getP2().x) { //AND System.out.println("1.2: Comparing L1S: " + l1.getP1().x + " larger than L2S: " + l2.getP1().x); if (l1.getP1().x > l2.getP1().x) { System.out.println("1: Success. NEXT"); //IT IS INTERSECTED continue; } else { //FAILED SECOND COMPARISON System.out.println("1: Fail"); } } else { System.out.println("Checking other line"); } System.out.println("2.0: L2S: " + l2.getP1().x + " larger than L1S: " + l1.getP1().x); } //If l2 is starting after, then comparisons are based around l2.s else if(l2.getP1().x > l1.getP1().x) { System.out.println("2.1: Comparing L2S: " + l1.getP1().x + " less than L1E: " + l2.getP2().x); if (l2.getP1().x < l1.getP2().x) { //AND System.out.println("2.2: Comparing L2S: " + l2.getP1().x + " larger than L1S: " + l1.getP1().x); if (l2.getP1().x > l1.getP1().x) { System.out.println("2: Success"); //IT IS INTERSECTED //continue; } else { //FAILED SECOND COMPARISON System.out.println("2: Fail"); //return false; } } else { System.out.println("Failed second comparison RETURN FALSE"); return false; } //return false; } else{ System.out.println("NEITHER RETURN FALSE"); return false; } */ import org.opencv.core.*; import org.opencv.core.Point; import org.opencv.highgui.HighGui; import org.opencv.imgcodecs.Imgcodecs; import org.opencv.imgproc.Imgproc; import static org.opencv.core.Core.FILLED; import static org.opencv.core.CvType.CV_8UC3; import static org.opencv.highgui.HighGui.imshow; import static org.opencv.imgcodecs.Imgcodecs.imwrite; import java.io.File; import java.util.ArrayList; //REFERENCES: //https://docs.opencv.org/3.4.3/d9/db0/tutorial_hough_lines. //https://stackoverflow.com/questions/43443309/count-red-pixel-in-a-given-image //https://www.wikihow.com/Calculate-Percentage-in-Java //https://riptutorial.com/opencv/example/21963/converting-an-mat-object-to-an-bufferedimage-object //https://beginnersbook.com/2013/12/java-arraylist-of-object-sort-example-comparable-and-comparator/ //https://www.programiz.com/java-programming/examples/standard-deviation //https://www.geeksforgeeks.org/how-to-remove-duplicates-from-arraylist-in-java/ //https://stackoverflow.com/questions/7988486/how-do-you-calculate-the-variance-median-and-standard-deviation-in-c-or-java/7988556 //https://stackoverflow.com/questions/10396970/sort-a-list-that-contains-a-custom-class //https://stackoverflow.com/questions/37946482/crop-images-area-with-opencv-java //https://docs.opencv.org/3.4/dd/dd7/tutorial_morph_lines_detection.html //https://docs.opencv.org/3.4/d0/d49/tutorial_moments.html //https://docs.opencv.org/2.4/doc/tutorials/imgproc/shapedescriptors/moments/moments.html //https://docs.opencv.org/3.3.1/d3/dc0/group__imgproc__shape.html#ga17ed9f5d79ae97bd4c7cf18403e1689a //http://androiderstuffs.blogspot.com/2016/06/detecting-rectangle-using-opencv-java.html //https://stackoverflow.com/questions/23327502/opencv-how-to-draw-minarearect-in-java //https://stackoverflow.com/questions/30056910/opencv-java-modify-pixel-values //GOAL for 21st //Classifier 01 //Have args so can call "java image-identification-classifier01 XX XX" //args can be parameters in algorthim such as threshold or theta? //Run on 5000 images. //Record success rates //All done with makefile //But first understand houghline transform //Know what the algorithm being used is doing. //MAke constants for this classifier //Make java be able to run on CMD line public class MainMorph { //CODE VERSIONS static int CODE_VERSION = 8; static int IMAGE_VERSION = 3; //GLOBAL_CONSTANTS static double THRESHOLD_C = 4; static double THRESHOLD_AREA_SIZE = 1000; static double THRESHOLD_AREA_COUNT = 2; // private static void imageViewer(String winName, Mat img) { try { //Internal display - Overview - Will Distort High Res images if(IMAGE_VERSION == 1) { HighGui.namedWindow(winName, HighGui.WINDOW_NORMAL); HighGui.resizeWindow(winName, 1000, 1000); imshow(winName, img); HighGui.moveWindow(winName, 500, 0); HighGui.waitKey(0); HighGui.destroyWindow(winName); } //Internal display - Segmented - Will _NOT_ Distort High Res images if(IMAGE_VERSION == 2) { HighGui.namedWindow(winName, HighGui.WINDOW_AUTOSIZE); HighGui.resizeWindow(winName, 1000, 1000); imshow(winName, img); HighGui.moveWindow(winName, 500, 0); HighGui.waitKey(0); HighGui.destroyWindow(winName); } //External display - Save Images for manual viewing if(IMAGE_VERSION == 3) { //save file (testing purposes) imwrite(winName+".jpg", img); } } catch (Exception e){ e.printStackTrace(); } } //MAIN public static void main(String[] args) { System.loadLibrary(Core.NATIVE_LIBRARY_NAME); try { //Variables System.out.println("Running code version: " + CODE_VERSION); Mat edgesDetected = new Mat(); Mat mid = new Mat(); Mat edgesDetectedRGB = new Mat(); Mat clustersFoundRGB = new Mat(); String testDirectory = "/Scratch/cpb16/is-sheet-music-encore/image-identification-dev-02/image-identification-development/"; String directory = "/Scratch/cpb16/is-sheet-music-encore/download-images/MU/"; String hiresDirectory = "/Scratch/cpb16/is-sheet-music-encore/hires-download-images/"; //!!!!!!!!!!!!!!!!!!!!!!!!!!!NOT!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //mdp.39015097852365-2.png 176 lines Contents page. //mdp.39015097852555-3.png 76 lines //!!!!!!!!!!!!!!!!!!!!!!!!!!!NOTNOT!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //coo.31924062612282-9.png 8 lines //String default_file = directory+"NotSheetMusic/coo.31924062612282-9.png"; //String default_file = directory+"NotSheetMusic/mdp.39015097852365-2.png"; //String default_file =testDirectory+"TestImages/NotNot/mdp.39015080972303-3.png"; //WHY GREY? //String default_file =hiresDirectory+"BK/NotSheetMusic/aeu.ark+=13960=t2q53nq6w-6.png"; //String default_file =hiresDirectory+"BK/NotSheetMusic/aeu.ark+=13960=t9z03w65z-4.png"; //String default_file =hiresDirectory+"MU/NotSheetMusic/aeu.ark+=13960=t0dv28v9r-1.png"; //String default_file =hiresDirectory+"MU/SheetMusic/emu.010001066823-9.png"; //String default_file =hiresDirectory+"MU/NotSheetMusic/mdp.39015096363935-1.png"; String default_file =hiresDirectory+"MU/SheetMusic/coo.31924062612282-9.png"; //System.out.println(default_file); //String default_file = "/Scratch/cpb16/is-sheet-music-encore/image-identification-terminal/TestImages/test-coo.31924062612282-9.png"; //String default_file = testDirectory+"TestImages/MorphTester.png"; //String default_file = testDirectory+"TestImages/NotSheetMusic01.png"; //String default_file = testDirectory+"TestImages/NotSheetMusic02.png"; //String default_file = testDirectory+"TestImages/SheetMusic01.png"; //String default_file = testDirectory+"TestImages/SheetMusic02.png"; //String default_file = testDirectory+"TestImages/vLine.png"; String filename = ((args.length > 0) ? args[0] : default_file); File file = new File(filename); if(!file.exists()){System.err.println("Image not found: "+ filename);} int horizontalLineCount =0; // Load an image Mat original1 = Imgcodecs.imread(filename, Imgcodecs.IMREAD_GRAYSCALE); System.out.println("Width: " + original1.width() + " Height: " + original1.height()); Mat original = original1.clone(); Imgproc.adaptiveThreshold(original1, original,255, Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C,Imgproc.THRESH_BINARY_INV, 15, THRESHOLD_C); //TEST PARAMETERSImgproc.adaptiveThreshold(original, edgesDetected,255, Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C,Imgproc.THRESH_BINARY_INV, 531,1); //Imgproc.threshold(original,original, 127, 255, Imgproc.THRESH_BINARY); //****************MORPHOLOGY**************************************************************************************** //ADDIOTIONAL FILTERING TO STOP STREAKS //LOOK INTO STREAKS MORPHOGOLY. //****************MORPHOLOGY**************************************************************************************** // Create the images that will use to extract the horizontal and vertical lines //dynamic morphology?? if(CODE_VERSION == 1) { int hori = original.width(); int vert = original.height(); //Find ratio between 100 and width and 100 and height int divX = hori/10; int divY = vert/10; int sizeX = (hori/divX) * 10; int sizeY = (vert/divY) * 10; Mat test = original.clone(); imageViewer("Original", test); System.out.println("hori: " + hori + '\t' + "vert: " + vert); System.out.println("sizeX: " + sizeX + '\t' + "sizeY: " + sizeY); Mat kernelErode = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(sizeX, (sizeY/100))); Imgproc.erode(test,test,kernelErode); imageViewer("01 Erode", test); Mat kernelDialate = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(sizeX,(sizeY/10))); Imgproc.dilate(test, test, kernelDialate); imageViewer("02 Dialate", test); Mat kernelErodeAgain = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size((sizeX/10),(sizeY/5))); Imgproc.erode(test,test,kernelErodeAgain); imageViewer(" 03 Erode Again", test); Mat kernelClose = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size((sizeX/10)*3,(sizeY/10)*3)); Imgproc.morphologyEx(test,test,Imgproc.MORPH_CLOSE, kernelClose); imageViewer("04 Close", test); Imgproc.adaptiveThreshold(test, test,255, Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C,Imgproc.THRESH_BINARY_INV, 15, THRESHOLD_C); imageViewer("05 Binarized", test); Mat kernelOpen = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size((sizeX/10),(sizeY/20))); Imgproc.morphologyEx(test,test,Imgproc.MORPH_OPEN, kernelOpen); imageViewer(" 06 Open", test); Mat kernelDialateAgain = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size((sizeX/5),(sizeY/100))); Imgproc.dilate(test, test, kernelDialateAgain); imageViewer("07 Dialate", test); Mat kernelCloseAgain = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size((sizeX/10),(sizeY/2))); Imgproc.morphologyEx(test,test,Imgproc.MORPH_CLOSE, kernelCloseAgain); imageViewer(" 08 Close Again (Final)", test); } //Successful hardcode for morhpology if (CODE_VERSION == 2) { //MAKE SURE BLACK & WHITE Mat test = original.clone(); imageViewer("00 Binarized Original", test); Mat kernelErode = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(100,1)); Imgproc.erode(test,test,kernelErode); imageViewer("01 Erode", test); Mat kernelDialate = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(110,10)); Imgproc.dilate(test, test, kernelDialate); imageViewer("02 Dialate", test); Mat kernelErodeAgain = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(10,20)); Imgproc.erode(test,test,kernelErodeAgain); imageViewer(" 03 Erode Again", test); Mat kernelClose = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(35,20)); Imgproc.morphologyEx(test,test,Imgproc.MORPH_CLOSE, kernelClose); imageViewer("04 Close", test); // Imgproc.threshold(test,test, 127, 255, Imgproc.THRESH_BINARY); // imageViewer("05 Binarized", test); Mat kernelOpen = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(4,4)); Imgproc.morphologyEx(test,test,Imgproc.MORPH_OPEN, kernelOpen); imageViewer(" 06 Open", test); // Mat kernelDialateAgain = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(1,10)); // Imgproc.dilate(test, test, kernelDialateAgain); // imageViewer("07 Dialate", test); //FIGURE OUT FLOOD FILL!! Imgproc.floodFill(test,test, new Point(1,1), new Scalar(2)); Mat kernelCloseAgain = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(10,50)); Imgproc.morphologyEx(test,test,Imgproc.MORPH_CLOSE, kernelCloseAgain); imageViewer(" 08 Close Again (Final)", test); } //Tutorial/Demo Code if (CODE_VERSION == 3) { Mat horizontal = original.clone(); Mat vertical = original.clone(); // Specify size on horizontal axis int horizontal_size = horizontal.cols() / 50; // Create structure element for extracting horizontal lines through morphology operations Mat horizontalStructure = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(horizontal_size, 2)); // Apply morphology operations Imgproc.erode(horizontal, horizontal, horizontalStructure); Imgproc.dilate(horizontal, horizontal, horizontalStructure); // Show extracted horizontal lines imageViewer("horizontal", horizontal); // Specify size on vertical axis int vertical_size = vertical.rows() / 30; // Create structure element for extracting vertical lines through morphology operations Mat verticalStructure = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(1, vertical_size)); // Apply morphology operations Imgproc.erode(vertical, vertical, verticalStructure); Imgproc.dilate(vertical, vertical, verticalStructure); // Show extracted vertical lines imageViewer("vertical", vertical); // Inverse vertical image Core.bitwise_not(vertical, vertical); imageViewer("vertical_bit", vertical); // Extract edges and smooth image according to the logic // 1. extract edges // 2. dilate(edges) // 3. src.copyTo(smooth) // 4. blur smooth img // 5. smooth.copyTo(src, edges) // Step 1 Mat edges = new Mat(); Imgproc.adaptiveThreshold(vertical, edges, 255, Imgproc.ADAPTIVE_THRESH_MEAN_C, Imgproc.THRESH_BINARY, 3, -2); imageViewer("edges", edges); // Step 2 Mat kernel = Mat.ones(2, 2, CvType.CV_8UC1); Imgproc.dilate(edges, edges, kernel); imageViewer("dilate", edges); // Step 3 Mat smooth = new Mat(); vertical.copyTo(smooth); // Step 4 Imgproc.blur(smooth, smooth, new Size(2, 2)); // Step 5 smooth.copyTo(vertical, edges); // Show final result imageViewer("smooth - final", vertical); System.exit(0); } //Better morphology attempt - static if(CODE_VERSION ==4) { //Display Original imageViewer("original", original1); Mat test = original.clone(); Mat pre = original.clone(); Mat dst = new Mat(); imageViewer("00 Inverse Binarized Original", test); //remove large items of no interest pre proc //denoize //heal //fnd large images, write to a seperate mat. //draw these onto orignal image(binerized) in red //turn all red pixels in image to black //denoize Mat denoize = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(3,3)); Imgproc.morphologyEx(pre,pre, Imgproc.MORPH_OPEN, denoize); imageViewer("Denoize - PRE", pre); //close up gaps Mat gapCloser = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(5,5)); Imgproc.morphologyEx(pre,pre,Imgproc.MORPH_CLOSE, gapCloser); imageViewer("gap closer - PRE", pre); Mat kernelHighlightLarge = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(10, 10)); Imgproc.erode(pre,pre, kernelHighlightLarge); imageViewer("Highlight Large - PRE", pre); //change white pixels to red ArrayList contoursPre = new ArrayList(); Mat hierarchyPre = new Mat(); //PARAMETERS: input image, output array of arrays, output array, contour retrieval mode, contour approximation method. //(contours) output array of arrays: Detected contours. Each contour is stored as a vector of points //(hierarchy) output array: Optional output vector, containing information about the image topology. //https://docs.opencv.org/3.3.1/d3/dc0/group__imgproc__shape.html#ga17ed9f5d79ae97bd4c7cf18403e1689a Imgproc.findContours(pre, contoursPre, hierarchyPre, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE); //Draw contours and record areas Mat drawingPre = Mat.zeros(test.size(), CvType.CV_8UC3); Mat mask = new Mat(drawingPre.size(), CV_8UC3,new Scalar(0)); Scalar colorPre = new Scalar(255, 255, 255); Imgproc.drawContours(mask, contoursPre, -1, new Scalar(255, 255, 255), FILLED); Imgproc.fillPoly(drawingPre, contoursPre,colorPre); imageViewer("DRAWINGPRE", drawingPre); //FIIIIIIIIIIIIIIIIIIIIIIIIIIXXXXXXXXXXXX //Remove from main Mat Core.bitwise_not(mask,mask); imageViewer("MASK", mask); imageViewer("TEST", test); drawingPre.copyTo(test, mask); imageViewer("COMBINE", test); //start staff line detection Mat kernelErode = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(10,1)); Imgproc.erode(test,test,kernelErode); imageViewer("01 Erode plus pre", test); Mat kernelDilate = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(20,3)); Imgproc.dilate(test,test,kernelDilate); imageViewer("02 Dilate", test); Mat kernelOpening = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(4,4)); Imgproc.morphologyEx(test, test, Imgproc.MORPH_CLOSE, kernelOpening); imageViewer("03 Open", test); Mat kernelErode02 = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(8,8)); Imgproc.erode(test,test,kernelErode02); imageViewer("04 Erode (Final)", test); //DETECT OUTLINE AND FIND AREA OF THESE LINES. ArrayList contours = new ArrayList(); Mat hierarchy = new Mat(); //PARAMETERS: input image, output array of arrays, output array, contour retrieval mode, contour approximation method. //(contours) output array of arrays: Detected contours. Each contour is stored as a vector of points //(hierarchy) output array: Optional output vector, containing information about the image topology. //https://docs.opencv.org/3.3.1/d3/dc0/group__imgproc__shape.html#ga17ed9f5d79ae97bd4c7cf18403e1689a Imgproc.findContours(test, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE); //Draw contours and record areas Mat drawing = Mat.zeros(test.size(), CvType.CV_8UC3); Mat drawing2 = Mat.zeros(test.size(), CvType.CV_8UC3); int areaCounter = 0; for (int i = 0; i < contours.size(); i++) { double area = Imgproc.contourArea(contours.get(i)); if(area > THRESHOLD_AREA_SIZE ) { areaCounter++; Scalar color = new Scalar(0, 0, 255); Imgproc.drawContours(drawing, contours, i, color, 1); System.out.println("AREA: " + area); } } //Classifier Calculation if(areaCounter >= THRESHOLD_AREA_COUNT){ System.out.println("THIS IS SHEET MUSIC"); System.out.println(areaCounter); } //Show in a window imageViewer("Contours", drawing); } //Better morphology attempt - dynamic if(CODE_VERSION ==5) { int hori = original.width(); int vert = original.height(); //Find ratio between 100 and width and 100 and height int sizeX100 = 10 * (hori/68); int sizeY100 = 10 * (vert/46); int sizeX10 = (hori/68); int sizeY10 = (vert/46); int sizeX1 = (hori/68)/10; int sizeY1 = (vert/46)/10; //SizeX should always be a 68th * 10. Based off the defualt tester image "coo.*" //SizeT should always be a 46th * 10 System.out.println(hori + " " + vert + " " + sizeX1 + " " + sizeY1); //Display Original imageViewer("original", original1); Mat test = original.clone(); imageViewer("00 Inverse Binarized Original", test); //Remove very large and wide black spaces (8th of the page) //Mat kernelRemoveLarge = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(hori/8, vert/8)); //Imgproc.erode(test,test, kernelRemoveLarge); //imageViewer("Remove Large", test); //Eliminate things that are not long and thin Mat kernelErode = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(sizeX10,sizeY1)); //new Size(10,1)); Imgproc.erode(test,test,kernelErode); imageViewer("01 Erode", test); Mat kernelDilate = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(sizeX10*2,sizeY1*3)); //new Size(20,3)); Imgproc.dilate(test,test,kernelDilate); imageViewer("02 Dilate", test); Mat kernelClose = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(sizeX1*4,sizeY1*4)); //new Size(4,4)); Imgproc.morphologyEx(test, test, Imgproc.MORPH_CLOSE, kernelClose); imageViewer("03 Open", test); Mat kernelErode02 = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(sizeX1*8,sizeX1*8)); //new Size(8,8)); Imgproc.erode(test,test,kernelErode02); imageViewer("04 Erode (Final)", test); //DETECT OUTLINE AND FIND AREA OF THESE LINES. ArrayList contours = new ArrayList(); Mat hierarchy = new Mat(); //PARAMETERS: input image, output array of arrays, output array, contour retrieval mode, contour approximation method. //(contours) output array of arrays: Detected contours. Each contour is stored as a vector of points //(hierarchy) output array: Optional output vector, containing information about the image topology. //https://docs.opencv.org/3.3.1/d3/dc0/group__imgproc__shape.html#ga17ed9f5d79ae97bd4c7cf18403e1689a Imgproc.findContours(test, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE); //Draw contours and record areas Mat drawing = Mat.zeros(test.size(), CvType.CV_8UC3); int areaCounter = 0; for (int i = 0; i < contours.size(); i++) { double area = Imgproc.contourArea(contours.get(i)); if(area > THRESHOLD_AREA_SIZE ) { areaCounter++; Scalar color = new Scalar(0, 0, 255); Imgproc.drawContours(drawing, contours, i, color, 1); System.out.println("AREA: " + area); } } //Classifier Calculation if(areaCounter >= THRESHOLD_AREA_COUNT){ System.out.println("THIS IS SHEET MUSIC"); System.out.println(areaCounter); } //Show in a window imageViewer("Contours", drawing); } //MASK UNDERSTANDING if(CODE_VERSION ==6) { String path ="/Scratch/cpb16/is-sheet-music-encore/hires-download-images/MU/NotSheetMusic/aeu.ark+=13960=t0dv28v9r-1.png"; Mat mask = new Mat(); Mat dst = new Mat(); //Get source image and binerize Mat src = Imgcodecs.imread(path, Imgcodecs.IMREAD_GRAYSCALE); Imgproc.adaptiveThreshold(original1, src,255, Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C,Imgproc.THRESH_BINARY_INV, 15, THRESHOLD_C); imageViewer("src", src); //Find unwanted material, then invert it so mask removes not keeps. Mat kernelErode = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(100,1)); Imgproc.erode(src,mask,kernelErode); Mat kernelDilate = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(110,10)); Imgproc.dilate(mask, mask, kernelDilate); Core.bitwise_not(mask,mask); imageViewer("mask", mask); //Copy source image to new Mat, with mask in use src.copyTo(dst, mask); imageViewer("dst", dst); } //Mask implementation if(CODE_VERSION ==7) { //Display Original imageViewer("original", original1); Mat src = original.clone(); Mat test = original.clone(); Mat mask = new Mat(); Mat dst = new Mat(); imageViewer("00 Inverse Binarized Original", src); //denoize Mat denoize = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(3,3)); Imgproc.morphologyEx(src,mask, Imgproc.MORPH_OPEN, denoize); imageViewer("01 Denoize - mask", mask); //close up gaps Mat gapCloser = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(5,5)); Imgproc.morphologyEx(mask,mask,Imgproc.MORPH_CLOSE, gapCloser); imageViewer("02 gap closer - mask", mask); //Isolate large items Mat isolateLarge = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(8, 8)); Imgproc.morphologyEx(mask,mask,Imgproc.MORPH_OPEN, isolateLarge); imageViewer("03 Isolate Large - mask", mask); Core.bitwise_not(mask,mask); //Remove unwanted large items from image src.copyTo(dst, mask); imageViewer("04 Large Items Removed", dst); //start staff line detection Mat kernelErode = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(10,1)); Imgproc.erode(dst,test,kernelErode); imageViewer("11 Erode plus pre", test); Mat kernelDilate = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(20,3)); Imgproc.dilate(test,test,kernelDilate); imageViewer("12 Dilate", test); Mat kernelOpening = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(4,4)); Imgproc.morphologyEx(test, test, Imgproc.MORPH_CLOSE, kernelOpening); imageViewer("13 Open", test); Mat kernelErode02 = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(8,8)); Imgproc.erode(test,test,kernelErode02); imageViewer("14 Erode (Final)", test); //DETECT OUTLINE AND FIND AREA OF THESE LINES. ArrayList contours = new ArrayList(); Mat hierarchy = new Mat(); //PARAMETERS: input image, output array of arrays, output array, contour retrieval mode, contour approximation method. //(contours) output array of arrays: Detected contours. Each contour is stored as a vector of points //(hierarchy) output array: Optional output vector, containing information about the image topology. //https://docs.opencv.org/3.3.1/d3/dc0/group__imgproc__shape.html#ga17ed9f5d79ae97bd4c7cf18403e1689a Imgproc.findContours(test, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE); //Draw contours and record areas Mat drawing = Mat.zeros(test.size(), CvType.CV_8UC3); int areaCounter = 0; Imgproc.drawContours(drawing, contours, -1, new Scalar(0, 255, 0), FILLED); // for (int i = 0; i < contours.size(); i++) { // Scalar color = new Scalar(0, i, i); // double area = Imgproc.contourArea(contours.get(i)); // Imgproc.drawContours(drawing, contours, i, color, FILLED); // System.out.println("AREA: " + area); // // } imageViewer("Contours found", drawing); //Classifier Calculation if(areaCounter >= THRESHOLD_AREA_COUNT){ System.out.println("THIS IS SHEET MUSIC"); System.out.println(areaCounter); } } //Mask implementation - HIGH RES NUMBER MOD if(CODE_VERSION ==8) { //Display Original imageViewer("original", original1); Mat src = original.clone(); Mat test = original.clone(); Mat mask = new Mat(); Mat dst = new Mat(); imageViewer("00 Inverse Binarized Original", src); //Close then Open // Mat firstKernel = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(10,10)); // Imgproc.morphologyEx(src, mask, Imgproc.MORPH_CLOSE, firstKernel); // imageViewer("01 Closed - mask", mask); // // Mat secondKernel = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(10,10)); // Imgproc.morphologyEx(src,mask, Imgproc.MORPH_OPEN, secondKernel); // imageViewer("02 Open - mask", mask); //denoize Mat denoize = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(5,5)); Imgproc.morphologyEx(src,mask, Imgproc.MORPH_OPEN, denoize); imageViewer("01 Denoize - mask", mask); //close up gaps Mat gapCloser = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(5,5)); Imgproc.morphologyEx(mask,mask,Imgproc.MORPH_CLOSE, gapCloser); imageViewer("02 gap closer - mask", mask); //Isolate large items Mat isolateLarge = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(8, 8)); Imgproc.morphologyEx(mask,mask,Imgproc.MORPH_OPEN, isolateLarge); imageViewer("03 Isolate Large - mask", mask); Core.bitwise_not(mask,mask); //Remove unwanted large items from image src.copyTo(dst, mask); imageViewer("04 Large Items Removed", dst); //start staff line detection Mat kernelErode = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(15,2)); //10,2 Imgproc.erode(dst,test,kernelErode); imageViewer("11 Erode plus pre", test); Mat kernelDilate = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(10,4)); //20,3 Imgproc.dilate(test,test,kernelDilate); imageViewer("12 Dilate", test); Mat kernelOpening = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(10,4)); //4,4 Imgproc.morphologyEx(test, test, Imgproc.MORPH_CLOSE, kernelOpening); imageViewer("13 Open", test); Mat kernelErode02 = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(10,4)); //10,1 Imgproc.erode(test,test,kernelErode02); imageViewer("14 Erode (Final)", test); //DETECT OUTLINE AND FIND AREA OF THESE LINES. ArrayList contours = new ArrayList(); Mat hierarchy = new Mat(); //PARAMETERS: input image, output array of arrays, output array, contour retrieval mode, contour approximation method. //(contours) output array of arrays: Detected contours. Each contour is stored as a vector of points //(hierarchy) output array: Optional output vector, containing information about the image topology. //https://docs.opencv.org/3.3.1/d3/dc0/group__imgproc__shape.html#ga17ed9f5d79ae97bd4c7cf18403e1689a Imgproc.findContours(test, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE); //Draw contours and record areas Mat drawing = Mat.zeros(test.size(), CvType.CV_8UC3); int areaCounter = 0; //Have created a preprocess to remove large objects. //Need to now finalized Classifier, re try area detection. //Paths to take - rectangle boxes around detected contours over threshold (area or perimeter) //Just use area and periemter to determine if sheet music //Discuss with david before weekend perhaps? Imgproc.drawContours(drawing, contours, -1, new Scalar(0, 255, 0), 1); //USES LINE_8 // for (int i = 0; i < contours.size(); i++) { // Scalar color = new Scalar(0, i, i); // double area = Imgproc.contourArea(contours.get(i)); // Imgproc.drawContours(drawing, contours, i, color, FILLED); // System.out.println("AREA: " + area); // // } imageViewer("Contours found", drawing); //Classifier Calculation if(areaCounter >= THRESHOLD_AREA_COUNT){ System.out.println("THIS IS SHEET MUSIC"); System.out.println(areaCounter); } } //USE stuc element, to rule out large wide and long pieces of black and white. //****************MORPHOLOGY**************************************************************************************** //BufferedImage toBeClassifiedImg = toBufferedImage(edgesDetectedRGB); //Display Results //HighGui.imshow("Source", original); //HighGui.imshow("Just Edges", justEdges); //TESTING imshow("LINESFOUND", edgesDetectedRGB); HighGui.resizeWindow("LINESFOUND", 1000,1000); //HighGui.imshow("CLUSTERS FOUND", clustersFoundRGB); //HighGui.imshow("Detected Lines (in red) - negative", edgesDetectedRGBProb); //COUNT OF LINES CLASSIFICATION //System.out.println("LINE CLUSTER RESULT: " + ClassifierLineClusterOLD(toBeClassifiedImg).get(0) + '\t' + "LinesFound: " + ClassifierLineClusterOLD(toBeClassifiedImg).get(1) + '\t' + "ClustersFound: " + ClassifierLineClusterOLD(toBeClassifiedImg).get(2)); //System.out.println("NEW CLUSTER RESULTS: " + ClassifierLineClusterPt(pointArrayList,clustersFoundRGB).get(0) + '\t' + "LinesFound: " + horizontalLineCount + '\t' + "ClustersFound: " + ClassifierLineClusterPt(pointArrayList,clustersFoundRGB).get(1)); //System.out.println(ClassifierLineClusterPt(pointArrayList, clustersFoundRGB)); //System.out.println("TEST: " + LineCountOrCluster(horizontalLineCount, pointArrayList, clustersFoundRGB)); // Wait and Exit HighGui.waitKey(); System.exit(0); } catch(Exception e){ System.err.println(e); } } }