OpenCv圆函数可以用来画一个奇数直径的圆吗? [英] Can the OpenCv circle function be used to draw a circle with an odd diameter?

查看:66
本文介绍了OpenCv圆函数可以用来画一个奇数直径的圆吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将一个直径为 15 的圆画成一个 15 x 15 的矩阵.为此,我尝试了 OpenCv circle 函数和 shift 函数.

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 function in a correct way or wheather it is not possible what I would like to do.

我得到的最好的结果是以下大小为 16 像素的不对称圆:

The best I achieve is the following unsymmetric circle with a size of 16 pixels:

如何得到一个直径为 15 像素的对称圆?

How can I get a symmetric circle with a diameter of 15 pixels?

我使用的代码:

    import cv2
    import numpy as np  

    circle_diameter = 15
    circular_mask = np.zeros((circle_diameter, circle_diameter, 1), dtype='uint8')
    #Draw circle with subpixel accuracy
    shift = 4
    factor = (1 << shift)
    cv2.circle(circular_mask, (int(round((circle_diameter/2) * factor)), int(round((circle_diameter/2) * factor))), int(round((circle_diameter/2) * factor)), (255), -1, shift=shift)

    circular_mask = cv2.resize(circular_mask,None,fx=5,fy=5)
    cv2.imshow("mask", circular_mask)

谢谢

推荐答案

好的,给你.

我会用 C++ 语法编写,但对于 Python 应该是一样的.

I'll write in C++ syntax, but should be same for Python.

似乎 cv::circle 中的像素坐标是指像素中心.

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 size
    const int 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 pixel

    int 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);

但结果似乎有一些像素整流问题,尽管看起来像蜜蜂居中且半径为 7.5.结果已调整大小以进行可视化.

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.

半径为 6.5 的相同代码(但调整大小因子较小)给出了此图像(在绘制过程中看起来像一些圆形片段).

Same code (but smaller resize factor) with radius 6.5 gives this image (looks like some rounding fragments during drawing).

另一个测试,使用更多位来表示接近 7.5 半径的数字,但要小几位,以减少绘图中的舍入碎片:

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 artifacts

    const int shift = 5; // more bits for fraction
    int radiusLow = 7;
    int radiusShift = (radiusLow << shift) + (1<<(shift-1)) -1; // 7+ 2^-1 - 2^-5 

    // center of the 17x17 image
    int x = 8<<shift;
    int y = 8<<shift;

这篇关于OpenCv圆函数可以用来画一个奇数直径的圆吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆