Can The Opencv Circle Function Be Used To Draw A Circle With An Odd Diameter?
I would like to draw a circle with a diameter of 15 into a matrix of 15 by 15. For this I tried the OpenCv circle function and the shift function. I am not sure whether I use the f
Solution 1:
Ok, here you go.
I'll write in C++ syntax, but should be same for Python.
It seems like the pixel coordinates in cv::circle refers to the pixel center.
cv::Mat img = cv::Mat::zeros(15, 15, CV_8UC1);
// in this code, shift must be >= 1 because of the later line (1<<(shift-1)) to add the .5 for an arbitrary shift sizeconstint shift = 2;
int radiusLow = 7;
int radiusShift = (radiusLow << shift) + (1<<(shift-1)); // + .5//int x = (7 << shift) + (1<<(shift-1)); // wrong, because the pixel position seems to be the pixel center already. 7.5 would be the right ede of the pixel//int y = (7 << shift) + (1<<(shift-1)); // wrong, because the pixel position seems to be the pixel center already. 7.5 would be the right ede of the pixelint x = 7<<shift;
int y = 7<<shift;
cv::circle(img, cv::Point(x, y), radiusShift, cv::Scalar::all(255), -1, 8, shift);
//cv::resize(img, img, cv::Size(), 50, 50); // for visualization
cv::imshow("img", img);
cv::waitKey(0);
But the result seems to have some pixel disrectization problems, though looks like as beeing centered and with 7.5 radius. Result is resized for visualization.
Same code (but smaller resize factor) with radius 6.5 gives this image (looks like some rounding fragments during drawing).
Another test, using more bits to represent a number close to 7.5 radius, but a few bits smaller, to reduce rounding fragments in drawing:
cv::Mat img = cv::Mat::zeros(17, 17, CV_8UC1); // 2 pixels bigger for visualization of possible artifactsconstint shift = 5; // more bits for fractionint radiusLow = 7;
int radiusShift = (radiusLow << shift) + (1<<(shift-1)) -1; // 7+ 2^-1 - 2^-5 // center of the 17x17 imageint x = 8<<shift;
int y = 8<<shift;
Solution 2:
Mickas Code in Python:
import cv2
import numpy as np
circle_diameter = 15
circular_mask = np.zeros((circle_diameter+2, circle_diameter+2, 1), dtype='uint8') #Plus two for visualizationshift = 5
radius_low = np.floor(circle_diameter/2)
radius_shifted = (np.uint64(radius_low) << np.uint64(shift)) + (np.uint64(1)<<np.uint64((shift-1))) -1; # 7+ 2^-1 - 2^-5
circle_x = 8 << shift
circle_y = 8 << shift
cv2.circle(circular_mask, (circle_x,circle_y), int(radius_shifted), (255), -1, shift=shift)
circular_mask = cv2.resize(circular_mask,None,fx=5,fy=5)
cv2.imshow("mask", circular_mask)
Post a Comment for "Can The Opencv Circle Function Be Used To Draw A Circle With An Odd Diameter?"