Python:如何创建一个离散化的子矩阵? [英] Python: how to create a submatrix discretizing a circle?

查看:147
本文介绍了Python:如何创建一个离散化的子矩阵?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在一个满是 zeros 的2D方格(矩阵)中,我需要创建一个满载 ones ,该子矩阵的形状尽可能接近圆形。我知道在使用单元格或像素时不能精确地表示一个圆,因此我的目标是一个离散的圆。



我能想到的最好的事情是这个代码,它生成方形子矩阵(下图中的蓝色方块): $ _
$ b

  from __future__ import division 
import numpy
import matplotlib.pyplot as plt
import matplotlib.colors as mc
import random
import os
import math

n = 101 #Grid size
empty_lattice = numpy.zeros((n,n))#空2D网格
x = int(numpy.random.uniform(0,n-1))#X坐标。左上角
y = int(numpy.random.uniform(0,n-1))#Y coord。左上角
side = int(numpy.random.uniform(15,n))#平方近似圆的边数
max_y = ny#检查子矩阵原点y和矩阵垂直边界
max_x = nx#检查子矩阵原点x与矩阵水平边界之间的距离
max_width = 0#初始化加载子矩阵
的最大宽度,如果max_y max_width = max_y
else:
max_width = max_x
if side> max_width :
为范围内的(0,max_width):
为范围内的j(0,max_width):
empty_lattice [x + i] [y + j] = 1
else:
在范围内(0,side):
在范围内(0,side):
empty_lattice [x + i] [y + j] = 1

现在,这可以转化为以下图片,但正如您所知,存在明显的差异在区域内的蓝色方块和内接圆之间的费用:



我的问题::我怎么能修改我的代码,以便能够平滑我的方块的角落,以便看起来类似于圆圈的东西出现? strong>编辑



即使它们并未完全驻留在网格边界内,也应该绘制圆圈(查看图像)。 b $ b

解决方案

这个函数填充了一个看起来不错的1的圆。

  def fill_cell(cell,corner,rad):
m,n = cell.shape
ctr = corner [0] + m / 2,corner [1] + n / 2
x = np.arange(m) - ctr [0]
y = np.arange(n) - ctr [1]
X,Y = np.meshgrid(x,y,order = 'ij')#可以尝试order ='xy'
Z =( (x ** 2 + Y ** 2)≤rad** 2).astype(cell.dtype)
return Z
empty_lattice [:] = fill_cell(empty_lattice,(x,y) ,side / 2)

仓位 empty_lattice 是不正确的 - 因为你在定义 x,y 坐标和我的假设方面存在差异,但我认为你可以对此进行排序。



半径看起来不错,但可能会被一个整数关掉。



要填写多个圈子,可以遍历 x,y 值,并且
为一个切片分配点阵值(视图)

 

对于重叠的圆圈,我会研究某种逻辑分配方式

  empty_lattice [xyslice] | = fill_cell(...)


In a 2D square grid (matrix) full of zeros, I need to create a submatrix full of ones, with the shape of this submatrix being as close as possible to a circle. I know a circle cannot be precisely represented when you work with cells or pixels, therefore I aim at a discretized circle.

The best thing I could come up with was this code, which produces square submatrices (the blue square in the image below):

from __future__ import division 
import numpy
import matplotlib.pyplot as plt
import matplotlib.colors as mc
import random
import os
import math

n=101 #Grid size
empty_lattice=numpy.zeros((n,n)) #The empty 2D grid
x=int(numpy.random.uniform(0,n-1)) #X coord. top left corner
y=int(numpy.random.uniform(0,n-1)) #Y coord. top left corner
side=int(numpy.random.uniform(15,n)) #Side of the square approximating the circle
max_y=n-y #Checks the distance between the y of the submatrix origin and the matrix vertical boundary
max_x=n-x #Checks the distance between the x of the submatrix origin and the matrix horizontal boundary
max_width=0 #Initializes a maximum width for the loading submatrix
if max_y<max_x: #This assigns the minimum value between max_y and max_x to max_width, so that the submatrix is always a square
    max_width=max_y
else:
    max_width=max_x     
if side>max_width:
    for i in range(0,max_width):
        for j in range(0, max_width):
            empty_lattice[x+i][y+j]=1
else:
    for i in range(0, side):
        for j in range(0, side):
            empty_lattice[x+i][y+j]=1

Now, visually this translates into the following image, but as you know there is a noticeable difference between the blue square and the inscribed circle in terms of area:

My question: how could I amend my code in order to be able to "smooth" the corners of my squares so that something which resembles a circle appears?

EDIT

The circles should be drawn even if they do not entirely reside within the grid boundaries (look at the image).

解决方案

This function fills in a circle of 1s that looks pretty good.

def fill_cell(cell, corner, rad):
    m, n = cell.shape
    ctr = corner[0]+m/2, corner[1]+n/2
    x = np.arange(m) - ctr[0]
    y = np.arange(n) - ctr[1]
    X,Y = np.meshgrid(x, y, order='ij')  # could try order='xy'
    Z = ((X**2 + Y**2)<= rad**2).astype(cell.dtype)
    return Z
empty_lattice[:] = fill_cell(empty_lattice, (x,y),side/2)

Position in empty_lattice is not right - because of a difference in how you are defining the x,y coordinates and my assumptions, but I think you can sort that out.

Radius looks good, though it might be off by an integer.

To fill in multiple circles, you could iterate over the x,y values, and assign lattice values for a slice (view)

xyslice = slice(x,15), slice(y,15)
empty_lattice[xyslice] = fill_cell(empty_lattice[xyslice],...)

For overlapping circles I'd look into some sort of logical assignment

empty_lattice[xyslice] |= fill_cell(...)

这篇关于Python:如何创建一个离散化的子矩阵?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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