I want to find the circles in the below image.I tried using OpenCV's Hough circle detection but it is not giving the proper results.
Is there any other way to find circles?
Here is sample code
vector<Vec3f> circles;
Mat src_gray,te;
cvtColor(tImg, src_gray, CV_BGR2GRAY);
GaussianBlur(src_gray, src_gray, Size(9, 9), 2, 2);
Canny(src_gray, te, 40, 240, 3);
/// Apply the Hough Transform to find the circles
HoughCircles(te, circles, CV_HOUGH_GRADIENT, 1, te.rows / 10, 120, 9, 5, 25);
Take contour,
1. find the centroid of the contour
2. find distance from the centroid to each contour pixels.
3. if this distance is almost same then it will be a circle.
See This link
Related
I'm trying to map a custom image to a 4-sided quad with a non-rectangular shape in p5.js. I know this is possible(and quite easy) using a WEBGL canvas and the texture() command, but I'm trying not to use WEBGL in my code simply because I don't like the WEBGL coding environment; and it seems kind of overkill to swap to a 3D canvas just for this(I don't need any other 3D objects in my program).
I'm looking for an in-built solution, or a custom library with something of this matter in it. I've tried both to some degree and have turned up empty-handed; which is odd because this seems like a relatively simple thing to ask for.
I'm also kind of stupid and I don't understand HTML in general. I use p5.js because of this, but I'm not against any kind of help: all is appreciated.
I've tried using a mixture of shearX() and shearY() but those would only work for an orthographic view; I'm going for perspective.
I have looked into brute-forcing it by literally going through each pixel in the quad and calculating the pixel color it should have based on the image, but haven't had this work yet. It also seems hecka laggy; and I'm looking for this quad to render in real-time.
If you don't want to use WebGL (or p5.js) there are other js libraries that can apply perspective warp via canvas, such as perspective.js.
Here's their example:
// ctx (CanvasRenderingContext2D): The 2D context of a HTML5 canvas element.
// image (Image): The image to transform.
var p = new Perspective(ctx, image);
p.draw([
[30, 30], // Top-left [x, y]
[image.width - 50, 50], // Top-right [x, y]
[image.width - 70, image.height - 30], // bottom-right [x, y]
[10, image.height] // bottom-left [x, y]
]);
This may be bit overkill, but warpPerspective() in opencv.js also support a similar transform.
Here's their example:
let src = cv.imread('canvasInput');
let dst = new cv.Mat();
let dsize = new cv.Size(src.rows, src.cols);
// (data32F[0], data32F[1]) is the first point
// (data32F[2], data32F[3]) is the sescond point
// (data32F[4], data32F[5]) is the third point
// (data32F[6], data32F[7]) is the fourth point
let srcTri = cv.matFromArray(4, 1, cv.CV_32FC2, [56, 65, 368, 52, 28, 387, 389, 390]);
let dstTri = cv.matFromArray(4, 1, cv.CV_32FC2, [0, 0, 300, 0, 0, 300, 300, 300]);
let M = cv.getPerspectiveTransform(srcTri, dstTri);
// You can try more different parameters
cv.warpPerspective(src, dst, M, dsize, cv.INTER_LINEAR, cv.BORDER_CONSTANT, new cv.Scalar());
cv.imshow('canvasOutput', dst);
src.delete(); dst.delete(); M.delete(); srcTri.delete(); dstTri.delete();
I am trying to get the transform matrix from one triangle to another. I am principally concerned about 2D. We will see for 3D later (but open to solutions).
I was reading this answer.
Now please correct me: if my first equilateral triangle, with sides of length 1, has its leftmost point located at the origin, its transform should be the identity matrix.
So, reading the solution above, the transform matrix I am looking for, should be triangle B matrix * inv(Identity) == B matrix.
I cannot wrap my head around that, because it seems wrong. In the given image, I want to transform blue to red, with blue having one point at the origin. The selected point of transform for the red triangle is always the closest to the origin.
The last missing image is the last transform merging Blue as Red (same triangle).
I am using Eigen (c++) for my transforms and calculation already.
Questions:
What info did I miss in the process?
What is the real transform matrix given those constraints?
Thanks
The inverted matrix is generated from the triangle you are translating from, not the destination. I've made a fiddle that demonstrates this here: https://jsfiddle.net/dwch1tju/
Let's say your first triangle has points at [0,0] [0.5,sin(60)] and [1,0] and the second triangle has points at [1.1,0.7] [0.9,1.9] and [1,0]. Then the triangle matrices are:
[[0, 0.5, 1],[0, 0.866, 0], [1, 1, 1]]
[[1.1, 0.9, 2.3], [0.7, 1.9, 0.6], [1, 1, 1]]
Demonstrated by:
const triangleMatrixA = createTriangleMatrix(triangleA);
const triangleMatrixB = createTriangleMatrix(triangleB);
Which creates a transform of
[[0.88, 0.56, -1.36], [0.07, 0.85, -0.67], [0, 0, 1]]
Demonstrated by:
const invertedMatrixB = invertMatrix(triangleMatrixB);
const multiplied = multiplyMatricies(triangleMatrixA, invertedMatrixB)
The fiddle then uses the transform on the three points in the second triangle, to show that they become the points of the first tringle in these lines:
const translatedA = multiplyPointByMatrix(multiplied, triangleB.a);
const translatedB = multiplyPointByMatrix(multiplied, triangleB.b);
const translatedC = multiplyPointByMatrix(multiplied, triangleB.c);
The first generated image in the fiddle shows the original location of the triangles and the second image shows that the translated points place the triangles in the same location.
The answer you link is not inverting a transform. It is inverting a triangle matrix that contains the coordinates of the triangle, then multiplying it by the other triangle matrix to create a transform.
how would a go about drawing the inner blue slice of this circle, to simulate varying stroke weight.
I have tried a approach where i draw the stroke by drawing small circles on each angle of the circle and increasing the radius on certain parts of the circle. But this doesnt give the right result because the circle gets "pixelated" in the edge, and it skews the circle outwards.
There is no easy way to accomplish this. Part of the difficulty is that Canvas, the underlying technology that p5.js uses to draw graphics, doesn't support variable stroke weights either. In Scalable Vector Graphics, which has similar limitations, the best way to accomplish this would be to describe the shape as the outer perimeter, and the perimeter of the inner void, and then fill the shape without any stroke. I think Canvas would support this approach, but I don't think it can be done easily with p5.js because there's now way to jump to a new position when drawing bezier curves with beginShape()/bezierVertex(). However, one way you could do this in p5.js would be to fill the outer shape and then "remove" the inner void. If you want to draw this on top of other existing graphics then the best way is to draw this shape to a separate p5.Graphics object which you then draw to your main canvas with image():
let sprite;
function setup() {
createCanvas(windowWidth, windowHeight);
sprite = createGraphics(100, 100);
sprite.noStroke();
sprite.fill('black');
sprite.angleMode(DEGREES);
sprite.circle(50, 50, 100);
// switch to removing elements from the graphics
sprite.erase();
// Translate and rotate to match the shape you showed in your question
sprite.translate(50, 50);
sprite.rotate(-45);
// Remove a perfect semi circle from one half, producing regular 5px stroke circle
sprite.arc(0, 0, 90, 90, -90, 90);
// Remove a half-ellipse from the other side of the circle, but this time the
// height matches the previous arc, but the width is narrower.
// Note: the angles for this arc overlap the previous removal by a few degrees
// to prevent there from being a visible seam in between the two removed shapes.
sprite.arc(0, 0, 70, 90, 85, 275, OPEN);
}
function draw() {
background('lightgray');
image(sprite, mouseX - 50, mouseY - 50);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>
I need to create a hexagon shape but am not able to actually calculate the matrix points by myself. I have a example for a triangle:
triangle.drawPolygon([
-32, 64, //First point
32, 64, //Second point
0, 0 //Third point
]);
I found the following website!
Polygon matrix coords calculator
Please check this neat piece of code I found:
glEnable(GL_LINE_SMOOTH);
glColor4ub(0, 0, 0, 150);
mmDrawCircle( ccp(100, 100), 20, 0, 50, NO);
glLineWidth(40);
ccDrawLine(ccp(100, 100), ccp(100 + 100, 100));
mmDrawCircle( ccp(100+100, 100), 20, 0, 50, NO);
where mmDrawCircle and ccDrawLine just draws these shapes [FILLED] somehow... (ccp means a point with the given x, y coordinates respectively).
My problem .... Yes, you guessed it, The line overlaps with the circle, and both are translucent (semi transparent). So, the final shape is there, but the overlapping part becomes darker and the overall shape looks ugly.. i.e, I would be fine if I was drawing with 255 alpha.
Is there a way to tell OpenGL to render one of the shapes in the overlapping parts??
(The shape is obviously a rectangle with rounded edges .. half-circles..)
You could turn on GL_DEPTH_TEST and render the line first and a little closer to the camera. When you then render the circle below, the fragments of the line won't be touched.
(You can also use the stencil buffer for an effect like this).
Note that this might still look ugly. If you want to use anti-aliasing you should think quite hard on which blending modes you apply and in what order you render the primitives.