I've used Canny and findContour to detect my contours of drawn coloured lines.
However, because of this, I am currently facing a problem of having lines being bounded.
What I want is to overlay and detect the entire line.
This is what I have now:
https://imgur.com/vnwu3Qf
I want the blue detection lines to cover the entire line that is being drawn. Not just the perimeter of the line drawn.
How is this possible?
The perimeter of pen-drawn line is highlighted with blue because you are using 1 as thickness in drawContours() function. To fill it with blue, set thickness = -1 in drawContours().
Refer this
Related
I want to detect a straight line in an image with python and get the thickness of the straight line.(The straight thickness I am looking for is ultimately the thickness of the long pole. What I want to add is the thickness occupied by the photo, not the actual thickness of the object.)
As far as I know, picking the contour from the image is one way, but finding the contour and then the thickness is another problem.
I have images such as below (I am pasting only a sketch here) where I want to calculate the center of symmetry and the displacement between the 2 marked zones in the image(Marked in Red and blue). Could anyone suggest a simple algorithm for this? (Please note the signal is symmetric to 180-degree rotation).
The idea is to calculate the center of symmetry between the red and blue zones
Here is my algorithm approach:
Distinguish the red and blue pixels in the image by thresholding: Lets say set the blue pixels to wihte(255) and set the red pixels(0) and set the rest of image to the (125) in a gray channel image.
Check all of the pixels horizontally in the middle row of the image.
While you are checking, if you hit the red pixel, then try to search blue one. However, if you hit red pixel again, then start searching blue again.
During the search after red pixel if you hit a blue pixel then you can easiy calculate the middle of it. Then re-start the process.
Here is a demonstration of search line:
Note: Since they are dashed lines, luckily you may pass them with gaps. To fix, this you can try couple of random different rows.
In OpenCV, i know how to draw circles, but is there a way to get back all the points that makeup the circle? I hope I dont have to go through calculating contours.
Thanks
If you know how to draw the circle,
Create a black image with the same size of as that of original image
Then draw the circle on the black image with white color
Now in this black image, check the points which are white
If you are using Python API, you can do as follows :
import numpy as np
import cv2
img = np.zeros((500,500),np.uint8)
cv2.circle(img,(250,250),100,255)
points = np.transpose(np.where(img==255))
You can do similar thing to the answer implemented in python in C/C++
If you know how to draw the circle,
Create a black image with the same size of as that of original image
Then draw the circle on the black image with white color
Now instead of checking which pixels have certain value you can find a contour (represented as vector of points) of the circle's edge.
To do this you can use OpenCV's findContours function which will give you the points on the circles edge.
Actually the background doesn't have to be black and the circle white, but the background should be plain and the circle should have different color than background.
i have been trying to draw a rounded rectangle with spacing in the border, but i cant seem to find a way to do this using the Canvas.RoundRect function, and i am not that good in maths to draw the edges myself, i can draw a rectangle with spacing using the Canvas.MoveTo and Canvas.LineTo functions, but i dont know how to make the edges rounded. Currently what i am doing is i make yellow rectangle at the place where i want to make the spacing in the border but the problem is when i am printing i have to directly draw on printer canvas and i have to draw on a transparent sheet, so a background color will cause problems. Anyone who can help me build a custom drawing routine or tell me how can i erase that area and still print on a transparent paper without any background color. The yellow background color is just for a preview, when i am drawing to a printer canvas the background is transparent.
See the image to know what i mean by spacing in the border line.
Thanks
You can exclude the gap by manipulating the clipping region of the current device context. Assuming that L, R, T and B are the coordinates of your yellow rectangle to make the gap, use the following code:
ExcludeClipRect(Canvas.Handle, L, T, R, B); // exclude the gap
Canvas.RoundRect(<whatever you already do here>);
SelectClipRgn(Canvas.Handle, 0); // reset the clipping region
You can draw your partial rounded rectangle yourself. Use MoveTo and LineTo for the straight portions, and use Arc for the corners.
The Arc function draws a portion of an ellipse. The first two pairs of coordinates to the function indicate the bounds of the ellipse. If you want the corners of your rectangle to be circular, then the ellipse is a circle, and X2 - X1 will equal Y2 - Y1. The second two pairs of coordinates indicate the starting and ending points on the circle; they'll be the same points you pass to MoveTo and LineTo for the straight portions. The arc is drawn counter-clockwise.
The cvLine() function can draw a straight line given two points P1(x1,y1) and P2(x2,y2). What I'm stuck at is getting the points on this line instead of drawing it straight away.
Suppose I draw a line (in green) AB and another line AC. If I follow all the pixels on line AB there will be a point where I encounter black pixels (the border of the circle that encloses A) before I reach B.
Again when traveling along the pixels on line AC black pixels will be encountered twice.
Basically I'm trying to get the points on the (green) lines, but cvLine() doesn't seem to return any point sequence structure. Is there any way to get these points using OpenCV?
A rather dumb approach would be to draw the line using cvLine() on a separate image, then find contours on it, then traverse that contour's CvSeq* (the line drawn) for the points. Both the scratch image and the original image being of same size we'd be getting the points' positions. Like I said, kinda dumb. Any enlightened approach would be great!
I think a CvLinIterator does what you want.
Another dirty but efficient way to find the number of points of intersection between circles and line without iterating over all pixels of the line is as follows:
# First, create a single channel image having circles drawn on it.
CircleImage = np.zeros((Height, Width), dtype=np.uint8)
CircleImage = cv2.circle(CircleImage, Center, Radius, 255, 1) # 255-color, 1-thickness
# Then create an image of the same size with only the line drawn on it
LineImage = np.zeros((Height, Width), dtype=np.uint8)
LineImage = cv2.line(LineImage, PointA, PointB, 255, 1) # 255-color, 1-thickness
# Perform bitwise AND operation
IntersectionImage = cv2.bitwise_and(CircleImage, LineImage)
# Count number of white pixels now for the number of points of intersection.
Num = np.sum(IntersectionImage == 255)
This method is also fast as instead of iterating over pixels, it is using OpenCV and numpy libraries.
On adding another circle in the image "CircleImage", you can find the number of interaction points of both the circles and the line AC.