diff --git a/8thWeek/Canny/Canny.pde b/8thWeek/Canny/Canny.pde index 296632c..d10ebac 100644 --- a/8thWeek/Canny/Canny.pde +++ b/8thWeek/Canny/Canny.pde @@ -1,176 +1,211 @@ -PImage img; +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; -enum kernelType { scale , blur , gaussian}; + +Capture cam; +PImage img; + +enum kernelType { + scale, blur, gaussian +}; int variable=0; void settings() { - size(1600, 600); + //size(1600, 600); + size(640, 480); } void setup() { - //thresholdBar0 = new HScrollbar(0, 560, 800, 20); - //thresholdBar1 = new HScrollbar(0, 580, 800, 20); - img = loadImage("src/board1.jpg"); - board1Thresholded = loadImage("src/board1Thresholded.bmp"); colorMode(HSB); - //board1Blurred = loadImage("src/board1Blurred.bmp"); - //board1Scharr = loadImage("src/board1Scharr.bmp"); - - noLoop(); // no interactive behaviour: draw() will be called only once. + 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() { - variable=(int)mouseX*255/width; - - image(img, 0, 0);//show image + if (cam.available() == true) { + cam.read(); + } + img = cam.get(); 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 + 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 ) { + if (kt == kernelType.scale ) { float[][] kernel1 = {{ 0, 0, 0 }, { 0, 2, 0 }, { 0, 0, 0 }}; - kernel = kernel1; - normFactor = 1f; - }else if(kt == kernelType.blur){ + 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{ + kernel = kernel2; + normFactor = 1f; + } else { float[][] gaussianKernel = {{ 9, 12, 9 }, { 12, 15, 12 }, { 9, 12, 9 }}; kernel = gaussianKernel; - normFactor = 0f; + normFactor = 0f; for (int i = 0; i< N; ++i) { for (int j = 0; j 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; + //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; }