diff --git a/8thWeek/Canny/Canny.pde b/8thWeek/Canny/Canny.pde index d10ebac..1fc9896 100644 --- a/8thWeek/Canny/Canny.pde +++ b/8thWeek/Canny/Canny.pde @@ -1,211 +1,211 @@ import processing.video.*; PImage board1Thresholded, board1Blurred, board1Scharr; int minHThreshold = 100, maxHThreshold =140; int minSThreshold = 100, maxSThreshold = 255; int minBThreshold = 45, maxBThreshold = 170; //HScrollbar thresholdBar0; //HScrollbar thresholdBar1; Capture cam; PImage img; enum kernelType { scale, blur, gaussian }; int variable=0; void settings() { //size(1600, 600); size(640, 480); } void setup() { colorMode(HSB); String[] cameras = Capture.list(); if (cameras.length == 0) { println("There are no cameras available for capture."); exit(); } else { println("Available cameras:"); for (int i = 0; i < cameras.length; i++) { println(cameras[i]); } //If you're using gstreamer0.1 (Ubuntu 16.04 and earlier), //select your predefined resolution from the list: cam = new Capture(this, cameras[21]); //If you're using gstreamer1.0 (Ubuntu 16.10 and later), //select your resolution manually instead: cam = new Capture(this, 640, 480, cameras[0]); cam.start(); } } void draw() { - if (cam.available() == true) { + /*if (cam.available() == true) { cam.read(); } img = cam.get(); int I = 100; img = thresholdHSB(img, minHThreshold, maxHThreshold, minSThreshold, maxSThreshold, minBThreshold, maxBThreshold ); img = convolute(img, kernelType.gaussian); img = scharr(img); img = threshold(img, I, false); img = new BlobDetection().findConnectedComponents(img, true); image(img, 0, 0); - drawLines(hough(img), img); + drawLines(hough(img), img);*/ - /* + variable=(int)mouseX*255/width; image(img, 0, 0);//show image int I = 100; PImage img1=img.copy(); img1 = thresholdHSB(img1, minHThreshold, maxHThreshold, minSThreshold, maxSThreshold, minBThreshold, maxBThreshold ); img1 = convolute(img1, kernelType.gaussian); img1 = scharr(img1); img1 = threshold(img1, I , false); img1 = new BlobDetection().findConnectedComponents(img1,true); drawLines(hough(img1),img1); image(img1, img.width, 0);//show processed image - */ + } //if inverted = false take values for 0 to threshol PImage threshold(PImage img, int threshold, boolean inverted) { PImage result = createImage(img.width, img.height, RGB); for (int i = 0; i < img.width * img.height; i++) { result.pixels[i]=brightness(img.pixels[i])>threshold^inverted?color(255):color(0); } return result; } PImage thresholdHSB(PImage img, int minH, int maxH, int minS, int maxS, int minB, int maxB) { PImage result = createImage(img.width, img.height, RGB); for (int i = 0; i < img.width * img.height; i++) { if (hue(img.pixels[i]) max )? value : max; buffer[x+y*img.width] = value; } } // ************************************* for (int y = 1; y < img.height - 1; y++) { // Skip top and bottom edges for (int x = 1; x < img.width - 1; x++) { // Skip left and right int val=(int) ((buffer[y * img.width + x] / max)*255); result.pixels[y * img.width + x]=color(val); } } return result; } PImage convolute(PImage img, kernelType kt) { int N = 3; //kernel size float[][] kernel; float normFactor ; if (kt == kernelType.scale ) { float[][] kernel1 = {{ 0, 0, 0 }, { 0, 2, 0 }, { 0, 0, 0 }}; kernel = kernel1; normFactor = 1f; } else if (kt == kernelType.blur) { float[][] kernel2 = {{ 0, 1, 0 }, { 1, 0, 1 }, { 0, 1, 0 }}; kernel = kernel2; normFactor = 1f; } else { float[][] gaussianKernel = {{ 9, 12, 9 }, { 12, 15, 12 }, { 9, 12, 9 }}; kernel = gaussianKernel; normFactor = 0f; for (int i = 0; i< N; ++i) { for (int j = 0; j> labelsEquivalences= new ArrayList>(); + ArrayList count=new ArrayList(); + + int currentLabel=0; + + for (int line=0; line < img0.height; ++line) { + TreeSet adjColor=new TreeSet(); + for (int x=0; x < img0.width; x++) { + if (img0.pixels[line*img0.width+x]==color(255)) { + adjColor.clear(); + + if (line>0) { + for (int i=x-1; i <= x+1; i++) {//check the three + if (0<=i && i(); + ts.add(++currentLabel); + labelsEquivalences.add(ts); + count.add(1); + labels[line*img0.width+x]=currentLabel; + } else { + if (adjColor.size()>1) { + for (Integer i : adjColor) { + labelsEquivalences.get(i-1).addAll(adjColor); + } + } + int first=adjColor.first(); + count.set(first-1, count.get(first-1)+1); + labels[line*img0.width+x]=first; + } + } + } + } + + //merge labelsEquivalences + for (int j=0; j ts=labelsEquivalences.get(j); + if (ts.size()>1) { + TreeSet acc=new TreeSet(); + for (Integer i : ts) { + TreeSet other=labelsEquivalences.get(i-1); + if(ts!=other){ acc.addAll(other);} + } + ts.addAll(acc); + for (Integer i : ts) { + labelsEquivalences.set(i-1,ts); + } + } + } + + //assess blob size + int[] blobSize=new int[labelsEquivalences.size()]; + for (int j=0; j ts=labelsEquivalences.get(j); + int sum=0; + for (Integer i : ts) { + sum+=count.get(i-1); + } + blobSize[j]=sum; + } + + //create ColorMap + int[] colorMap=new int[blobSize.length]; + if (onlyBiggest) { + int max =-1; + for(int i=0; i < blobSize.length; i++){ + max=max(max,blobSize[i]); + } + for(int i=0; i < blobSize.length; i++){ + colorMap[i]=blobSize[i]==max?color(255):color(0); + } + } else {//List> labelsEquivalences + for(TreeSet ts:labelsEquivalences){ + int rndColor=color(random(255),255,200); + for(Integer i:ts){ + colorMap[i-1]=rndColor; + } + } + } + + //colorize + for (int i=0; i < img0.width*img0.height; ++i) { + //int co=(labels[i])*256/7; + //labels[i]=color(co, 255, 200); + if(labels[i]!=0){ + img0.pixels[i]=colorMap[labels[i]-1]; + } + } + + return img0; + } +} diff --git a/8thWeek/Canny/Canny.pde b/MileStone2/Canny/Canny.pde similarity index 95% copy from 8thWeek/Canny/Canny.pde copy to MileStone2/Canny/Canny.pde index d10ebac..80be75f 100644 --- a/8thWeek/Canny/Canny.pde +++ b/MileStone2/Canny/Canny.pde @@ -1,211 +1,211 @@ -import processing.video.*; - -PImage board1Thresholded, board1Blurred, board1Scharr; -int minHThreshold = 100, maxHThreshold =140; -int minSThreshold = 100, maxSThreshold = 255; -int minBThreshold = 45, maxBThreshold = 170; -//HScrollbar thresholdBar0; -//HScrollbar thresholdBar1; - -Capture cam; -PImage img; - -enum kernelType { - scale, blur, gaussian -}; - -int variable=0; - -void settings() { - //size(1600, 600); - size(640, 480); -} - -void setup() { - colorMode(HSB); - String[] cameras = Capture.list(); - if (cameras.length == 0) { - println("There are no cameras available for capture."); - exit(); - } else { - println("Available cameras:"); - for (int i = 0; i < cameras.length; i++) { - println(cameras[i]); - } - //If you're using gstreamer0.1 (Ubuntu 16.04 and earlier), - //select your predefined resolution from the list: - cam = new Capture(this, cameras[21]); - //If you're using gstreamer1.0 (Ubuntu 16.10 and later), - //select your resolution manually instead: - cam = new Capture(this, 640, 480, cameras[0]); - cam.start(); - } -} - -void draw() { - if (cam.available() == true) { - cam.read(); - } - img = cam.get(); - int I = 100; - img = thresholdHSB(img, minHThreshold, maxHThreshold, minSThreshold, maxSThreshold, minBThreshold, maxBThreshold ); - img = convolute(img, kernelType.gaussian); - img = scharr(img); - img = threshold(img, I, false); - img = new BlobDetection().findConnectedComponents(img, true); - - image(img, 0, 0); - drawLines(hough(img), img); - - - - /* - variable=(int)mouseX*255/width; - - image(img, 0, 0);//show image - int I = 100; - PImage img1=img.copy(); - img1 = thresholdHSB(img1, minHThreshold, maxHThreshold, minSThreshold, maxSThreshold, minBThreshold, maxBThreshold ); - img1 = convolute(img1, kernelType.gaussian); - img1 = scharr(img1); - img1 = threshold(img1, I , false); - img1 = new BlobDetection().findConnectedComponents(img1,true); - - drawLines(hough(img1),img1); - image(img1, img.width, 0);//show processed image - */ -} - -//if inverted = false take values for 0 to threshol -PImage threshold(PImage img, int threshold, boolean inverted) { - PImage result = createImage(img.width, img.height, RGB); - for (int i = 0; i < img.width * img.height; i++) { - result.pixels[i]=brightness(img.pixels[i])>threshold^inverted?color(255):color(0); - } - return result; -} - -PImage thresholdHSB(PImage img, int minH, int maxH, int minS, int maxS, int minB, int maxB) { - PImage result = createImage(img.width, img.height, RGB); - for (int i = 0; i < img.width * img.height; i++) { - if (hue(img.pixels[i]) max )? value : max; - buffer[x+y*img.width] = value; - } - } - // ************************************* - - for (int y = 1; y < img.height - 1; y++) { // Skip top and bottom edges - for (int x = 1; x < img.width - 1; x++) { // Skip left and right - int val=(int) ((buffer[y * img.width + x] / max)*255); - result.pixels[y * img.width + x]=color(val); - } - } - return result; -} -PImage convolute(PImage img, kernelType kt) { - int N = 3; //kernel size - float[][] kernel; - float normFactor ; - if (kt == kernelType.scale ) { - float[][] kernel1 = {{ 0, 0, 0 }, - { 0, 2, 0 }, - { 0, 0, 0 }}; - kernel = kernel1; - normFactor = 1f; - } else if (kt == kernelType.blur) { - float[][] kernel2 = {{ 0, 1, 0 }, - { 1, 0, 1 }, - { 0, 1, 0 }}; - kernel = kernel2; - normFactor = 1f; - } else { - float[][] gaussianKernel = - {{ 9, 12, 9 }, - { 12, 15, 12 }, - { 9, 12, 9 }}; - kernel = gaussianKernel; - normFactor = 0f; - for (int i = 0; i< N; ++i) { - for (int j = 0; jthreshold^inverted?color(255):color(0); + } + return result; +} + +PImage thresholdHSB(PImage img, int minH, int maxH, int minS, int maxS, int minB, int maxB) { + PImage result = createImage(img.width, img.height, RGB); + for (int i = 0; i < img.width * img.height; i++) { + if (hue(img.pixels[i]) max )? value : max; + buffer[x+y*img.width] = value; + } + } + // ************************************* + + for (int y = 1; y < img.height - 1; y++) { // Skip top and bottom edges + for (int x = 1; x < img.width - 1; x++) { // Skip left and right + int val=(int) ((buffer[y * img.width + x] / max)*255); + result.pixels[y * img.width + x]=color(val); + } + } + return result; +} +PImage convolute(PImage img, kernelType kt) { + int N = 3; //kernel size + float[][] kernel; + float normFactor ; + if (kt == kernelType.scale ) { + float[][] kernel1 = {{ 0, 0, 0 }, + { 0, 2, 0 }, + { 0, 0, 0 }}; + kernel = kernel1; + normFactor = 1f; + } else if (kt == kernelType.blur) { + float[][] kernel2 = {{ 0, 1, 0 }, + { 1, 0, 1 }, + { 0, 1, 0 }}; + kernel = kernel2; + normFactor = 1f; + } else { + float[][] gaussianKernel = + {{ 9, 12, 9 }, + { 12, 15, 12 }, + { 9, 12, 9 }}; + kernel = gaussianKernel; + normFactor = 0f; + for (int i = 0; i< N; ++i) { + for (int j = 0; j 1) { + sliderPosition = sliderPosition + (newSliderPosition - sliderPosition); + } + } + + /** + * @brief Clamps the value into the interval + * + * @param val The value to be clamped + * @param minVal Smallest value possible + * @param maxVal Largest value possible + * + * @return val clamped into the interval [minVal, maxVal] + */ + float constrain(float val, float minVal, float maxVal) { + return min(max(val, minVal), maxVal); + } + + /** + * @brief Gets whether the mouse is hovering the scrollbar + * + * @return Whether the mouse is hovering the scrollbar + */ + boolean isMouseOver() { + if (mouseX > xPosition && mouseX < xPosition+barWidth && + mouseY > yPosition && mouseY < yPosition+barHeight) { + return true; + } else { + return false; + } + } + + /** + * @brief Draws the scrollbar in its current state + */ + void display() { + noStroke(); + fill(204); + rect(xPosition, yPosition, barWidth, barHeight); + if (mouseOver || locked) { + fill(0, 0, 0); + } else { + fill(102, 102, 102); + } + rect(sliderPosition, yPosition, barHeight, barHeight); + } + + /** + * @brief Gets the slider position + * + * @return The slider position in the interval [0,1] + * corresponding to [leftmost position, rightmost position] + */ + float getPos() { + return (sliderPosition - xPosition)/(barWidth - barHeight); + } +} diff --git a/MileStone2/Canny/HoughTransform.pde b/MileStone2/Canny/HoughTransform.pde new file mode 100644 index 0000000..428ecfd --- /dev/null +++ b/MileStone2/Canny/HoughTransform.pde @@ -0,0 +1,112 @@ +void drawLines(ArrayList lines,PImage edgeImg) { + + for (int idx = 0; idx < lines.size(); idx++) { + PVector line=lines.get(idx); + float r = line.x; + float phi = line.y; + // Cartesian equation of a line: y = ax + b + // in polar, y = (-cos(phi)/sin(phi))x + (r/sin(phi)) + // => y = 0 : x = r / cos(phi) + // => x = 0 : y = r / sin(phi) + // compute the intersection of this line with the 4 borders of + // the image + int x0 = 0; + int y0 = (int) (r / sin(phi)); + int x1 = (int) (r / cos(phi)); + int y1 = 0; + int x2 = edgeImg.width; + int y2 = (int) (-cos(phi) / sin(phi) * x2 + r / sin(phi)); + int y3 = edgeImg.width; + int x3 = (int) (-(y3 - r / sin(phi)) * (sin(phi) / cos(phi))); + // Finally, plot the lines + stroke(0, 255, 255); + if (y0 > 0) { + if (x1 > 0) + line(x0, y0, x1, y1); + else if (y2 > 0) + line(x0, y0, x2, y2); + else + line(x0, y0, x3, y3); + } else { + if (x1 > 0) { + if (y2 > 0) + line(x1, y1, x2, y2); + else + line(x1, y1, x3, y3); + } else + line(x2, y2, x3, y3); + } + } +} + +int minVotes=100; + +ArrayList hough(PImage edgeImg) { + + float discretizationStepsPhi = 0.06f; + float discretizationStepsR = 2.5f; + //int minVotes=300; + + + // dimensions of the accumulator + int phiDim = (int) (Math.PI / discretizationStepsPhi +1); + //The max radius is the image diagonal, but it can be also negative + int rDim = (int) ((sqrt(edgeImg.width*edgeImg.width + + edgeImg.height*edgeImg.height) * 2) / discretizationStepsR +1); + // our accumulator + int[] accumulator = new int[phiDim * rDim]; + // Fill the accumulator: on edge points (ie, white pixels of the edge + // image), store all possible (r, phi) pairs describing lines going + // through the point. + for (int y = 0; y < edgeImg.height; y++) { + for (int x = 0; x < edgeImg.width; x++) { + // Are we on an edge? + if (brightness(edgeImg.pixels[y * edgeImg.width + x]) != 0) { + // ...determine here all the lines (r, phi) passing through + // pixel (x,y), convert (r,phi) to coordinates in the + // accumulator, and increment accordingly the accumulator. + // Be careful: r may be negative, so you may want to center onto + // the accumulator: r += rDim / 2 + for (int phi=0; phi lines=new ArrayList(); + for (int idx = 0; idx < accumulator.length; idx++) { + if (accumulator[idx] > minVotes) { + ++totalLines; + // first, compute back the (r, phi) polar coordinates: + int accPhi = (int) (idx / (rDim)); + int accR = idx - (accPhi) * (rDim); + float r = (accR - (rDim) * 0.5f) * discretizationStepsR; + float phi = accPhi * discretizationStepsPhi; + lines.add(new PVector(r, phi)); + } + } + + if(totalLines<4){ + minVotes-=5; + }else if(totalLines>10){ + minVotes+=5; + } + + return lines; +} diff --git a/MileStone2/Canny/src/board1.jpg b/MileStone2/Canny/src/board1.jpg new file mode 100644 index 0000000..8766422 Binary files /dev/null and b/MileStone2/Canny/src/board1.jpg differ diff --git a/MileStone2/Canny/src/board1Blurred.bmp b/MileStone2/Canny/src/board1Blurred.bmp new file mode 100644 index 0000000..7eb8be8 Binary files /dev/null and b/MileStone2/Canny/src/board1Blurred.bmp differ diff --git a/MileStone2/Canny/src/board1Scharr.bmp b/MileStone2/Canny/src/board1Scharr.bmp new file mode 100644 index 0000000..688672d Binary files /dev/null and b/MileStone2/Canny/src/board1Scharr.bmp differ diff --git a/MileStone2/Canny/src/board1Thresholded.bmp b/MileStone2/Canny/src/board1Thresholded.bmp new file mode 100644 index 0000000..318f1de Binary files /dev/null and b/MileStone2/Canny/src/board1Thresholded.bmp differ diff --git a/MileStone2/Canny/src/board2.jpg b/MileStone2/Canny/src/board2.jpg new file mode 100644 index 0000000..dd326b2 Binary files /dev/null and b/MileStone2/Canny/src/board2.jpg differ diff --git a/MileStone2/Canny/src/board3.jpg b/MileStone2/Canny/src/board3.jpg new file mode 100644 index 0000000..8c1bbd3 Binary files /dev/null and b/MileStone2/Canny/src/board3.jpg differ diff --git a/MileStone2/Canny/src/board4.jpg b/MileStone2/Canny/src/board4.jpg new file mode 100644 index 0000000..34fa5cc Binary files /dev/null and b/MileStone2/Canny/src/board4.jpg differ diff --git a/MileStone2/Canny/src/nao.jpg b/MileStone2/Canny/src/nao.jpg new file mode 100644 index 0000000..1bce331 Binary files /dev/null and b/MileStone2/Canny/src/nao.jpg differ