'OpenCV get pixels on an ellipse
I'm trying to get the pixels of an ellipse from an image.
For example, I draw an ellipse on a random image (sample geeksforgeeks code):
import cv2
path = r'C:\Users\Rajnish\Desktop\geeksforgeeks\geeks.png'
image = cv2.imread(path)
window_name = 'Image'
center_coordinates = (120, 100)
axesLength = (100, 50)
angle = 0
startAngle = 0
endAngle = 360
color = (0, 0, 255)
thickness = 5
image = cv2.ellipse(image, center_coordinates, axesLength,
angle, startAngle, endAngle, color, thickness)
cv2.imshow(window_name, image)
Now, I want to get the pixel value of boundary line of ellipse. If it is possible I would like to get the pixel of ellipse using cv2.ellipse() back as an array of coordinates.
Can anyone help me with this please.
Solution 1:[1]
There is no direct OpenCV way probably to get these points of the ellipse but you can extract your points via indirect way like this:
mask = cv2.inRange(image, np.array(color), np.array(color))
contour = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[-2][0]
contour
will store the outer points of your red ellipse.
Here, what I have done is created a mask image of the ellipse and found the externalmost contour's points that is the required thing.
Solution 2:[2]
If you want to obtain points (locations) on an ellipse, you can use ellipse2Poly()
function.
If the argument type of ellipse2Poly()
is inconvenient, calculating by yourself is most convenient way.
This sample code is C ++, but what calculated is clear.
//Degree -> Radian
inline double RadFromDeg( double Deg ){ return CV_PI*Deg/180.0; }
//Just calculate points mathematically.
// Arguments are same as cv::ellipse2Poly (alothough ellipse parameters is cv::RotateRect).
void My_ellipse2Poly(
const cv::RotatedRect &EllipseParam,
double StartAngle_deg,
double EndAngle_deg,
double DeltaAngle_deg,
std::vector< cv::Point2d > &DstPoints
)
{
double Cos,Sin;
{
double EllipseAngleRad = RadFromDeg(EllipseParam.angle);
Cos = cos( EllipseAngleRad );
Sin = sin( EllipseAngleRad );
}
//Here, you will be able to reserve the destination vector size, but in this sample, it was omitted.
DstPoints.clear();
const double HalfW = EllipseParam.size.width * 0.5;
const double HalfH = EllipseParam.size.height * 0.5;
for( double deg=StartAngle_deg; deg<EndAngle_deg; deg+=DeltaAngle_deg )
{
double rad = RadFromDeg( deg );
double u = cos(rad) * HalfW;
double v = sin(rad) * HalfH;
double x = u*Cos + v*Sin + EllipseParam.center.x;
double y = u*Sin - v*Cos + EllipseParam.center.y;
DstPoints.emplace_back( x,y );
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Rahul Kedia |
Solution 2 |