问题描述
我想使用 skimage.draw.line
通过两个像素绘制一条锯齿线。问题是当我覆盖原始线时,由于四舍五入,经常会出现差异。
示例:
尝试通过 50x50 图像中的 (22,30) 和 (25,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 位置的相对误差量(红色像素):
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)