Published
Edited
Jun 19, 2020
Fork of OpenCV
Importers
Insert cell
Insert cell
Insert cell
Insert cell
circles = {
const cv = window.cv; // BUG!!! This will need to be reevaluated after loadOpenCv returns successfully
const src = cv.imread(image); // load source
const grey = src.clone(); // setup greyscale image
const blur = src.clone(); // setup blurred image
const canny = src.clone(); // setup canny edge detected image

// parameters
const ksize = new cv.Size(3, 3); // blurring kernel size
const sigma = [0, 0]; // gaussian kernal standard deviation [x, y]
const borderType = cv.BORDER_DEFAULT; // blur pixel extrapolation method
const method = cv.HOUGH_GRADIENT; // circle detection method, only this one is implemented in OpenCV
const dp = 1.1; // Resolution of the accumulator array. Votes cast are binned into squares set by dp size. Set too small and only perfect circles are found, set too high and noise collaborates to vote for non-circles.
const minDist = 12; // Minimum distance between the center (x, y) coordinates of detected circles. If the minDist is too small, multiple circles in the same neighborhood as the original may be (falsely) detected. If the minDist is too large, then some circles may not be detected at all.
const param1 = 190; // a number forwarded to the Canny edge detector (applied to a grayscale image) that represents the threshold1 passed to Canny(...). Canny uses that number to guide edge detection
const param2 = 14; // Accumulator threshold value for the cv2.HOUGH_GRADIENT method. The smaller the threshold is, the more circles will be detected (including false circles). The larger the threshold is, the more circles will potentially be returned.
const minRadius = 2; // Minimum size of the radius in pixels. Don't set minRadius and maxRadius far apart unless you want all possible circles that might be found in that range. If unknown, put zero as default.
const maxRadius = 14; // Maximum size of the radius (in pixels). Don't set minRadius and maxRadius far apart unless you want all possible circles found in that range. If unknown, put zero as default.
// convert input to greyscale
cv.cvtColor(src, grey, cv.COLOR_RGBA2GRAY, 0);
cv.imshow('greyscale', grey);

// blur image
cv.GaussianBlur(grey, blur, ksize, sigma[0], sigma[1], borderType);
cv.imshow('blur', blur);
// perform edge detection (for display only, incorporated within HoughCircles algorithm already)
cv.Canny(blur, canny, param1/2, param1, 3, false);
cv.imshow('edges', canny);
// find circles
const circles = new cv.Mat(); // setup circles vector
cv.HoughCircles(blur, circles, method, dp, minDist, param1, param2, minRadius, maxRadius);
// draw circles
const color = [255, 0, 0, 255]; // colour for drawing circles
const thickness = 1; // thickness to draw circles, negative values mean filled
const lineType = 8; // '8-connected' line
const shift = 0; // Number of fractional bits in the coordinates of the center and in the radius value.
const dst = cv.Mat.zeros(src.rows, src.cols, cv.CV_8U); // setup output image
let circleOut = []; // store circle details
for (let i = 0; i < circles.cols; ++i) {
let x = circles.data32F[i * 3];
let y = circles.data32F[i * 3 + 1];
let radius = circles.data32F[i * 3 + 2];
let center = new cv.Point(x, y);
circleOut.push({x: x, y: y, radius: radius});
cv.circle(src, center, radius, color, thickness, lineType, shift); // outline
cv.circle(src, center, 1, [0, 255, 0, 255], -1, lineType, shift);
}
cv.imshow('output', src);
src.delete(); dst.delete(); circles.delete(); grey.delete(); blur.delete(); canny.delete();
return circleOut;
}
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more