使用 numpy 和 skimage.draw.line 通过两个像素绘制中心线

问题描述

我想使用 skimage.draw.line 通过两个像素绘制一条锯齿线。问题是当我覆盖原始线时,由于四舍五入,经常会出现差异。 示例:

尝试通过 50x50 图像中的 (22,30) 和 (25,39) 点线。实线是绿色通道,叠加线是红色通道。黄色是重叠。我想要的结果不会产生可见的红色,只有黄色和绿色。

50 by 50 pixel image with line through points 22 comma 30 and 25 comma 39

我尝试生成更大的线条然后进行裁剪,但仍然遇到问题:

y0x0,ymxm=(np.array([0,0]),np.array([50,50]))
y1x1,y2x2=(np.array([22,30]),np.array([25,39]))
#rawzero3 is essentially trunc() but rounding up
#https://stackoverflow.com/q/46572699
yx_fin1=(y2x2-y1x1)*np.amin(\
    rawzero3((ymxm-(y2x2-y1x1))/(y2x2-y1x1)).astype(int))+y1x1
yx_fin2=(y0x0-1)-((y2x2-y1x1)*np.amin(\
    rawzero3((y0x0-(y2x2-y1x1))/(y2x2-y1x1)).astype(int))+y1x1)
zimg[tuple(map(tuple,np.array(draw.line(*yx_fin1,*yx_fin2)).T\
    [np.all((y0x0<=np.array(draw.line(*yx_fin1,*yx_fin2)).T)\
    &(np.array(draw.line(*yx_fin1,*yx_fin2)).T<ymxm),axis=1)].T))]=255

怎样才能达到我想要的结果?

编辑

我更新了代码以处理八分圆 0 之外的问题,类似于 Bresenham's Line Algorithm

def rawzero3(a):
    _a = np.abs(a)
    np.ceil(_a,_a) # inplace
    np.copysign(_a,a,out = _a)
    return _a
def fullline_pos(r0,c0,r1,c1,s):
    y0x0,np.array(s))
    y1x1,y2x2=(np.array([r0,c0]),np.array([r1,c1]))
    mdyx=(y2x2-y1x1)//np.gcd.reduce(y2x2-y1x1)#this will always be a whole number,the // makes it an int
    yx_fin1=mdyx*np.amin(rawzero3((ymxm-y1x1)/mdyx).astype(int))+y1x1 #should be slightly more efficient
    yx_fin2=(mdyx*np.amin(rawzero3((y0x0-y1x1)/mdyx).astype(int))+y1x1) #should be slightly more efficient
    if v: print(f'y0x0 {y0x0},ymxm {ymxm},y1x1 {y1x1},y2x2 {y2x2},(y2x2-y1x1) {(y2x2-y1x1)},yx_fin1 {yx_fin1},yx_fin2 {yx_fin2}')
    return tuple(map(tuple,*yx_fin2)).T[np.all((y0x0<=np.array(draw.line(*yx_fin1,*yx_fin2)).T)&(np.array(draw.line(*yx_fin1,axis=1)].T))
def fullline_neg(r0,s):
    sr,sc=np.array(s)-1
    r0_,c0_,r1_,c1_=sr-r0,sr-r1,c1
    coords=np.array(fullline_pos(r0_,c1_,s))
    coords[0]=sr-coords[0]
    return tuple(map(tuple,coords))
def fullline(r0,s):#returns a 2xN array of valid yx coordinates
    #r0,c1 are int,s is a 2d shape
    assert (r0,c0)!=(r1,c1)
    if r0==r1: return draw.line(r0,r0,s[1]-1)
    if c0==c1: return draw.line(0,s[0]-1,c1)
    if (r0<r1)==(c0<c1):
        return fullline_pos(r0,s,v=v)
    else:
        return fullline_neg(r0,v=v)

出于可视化目的,我对所有 x 和 y 值 0 到 49 运行 fullline(y,x,25,(50,50))。下图显示了每个 y,x 位置的相对误差量(红色像素):

enter image description here

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...