最近在学图形学绘制,想到了ImagePy框架的ROI涂抹交互很方便,于是啃起了绘制代码。
这里主要对ImagePy中一个填充工具进行难点讲解。
让我们好好学习Python中的图形学绘制吧。
例子代码来源:
https://github.com/Image-Py/imagepy/blob/master/imagepy/core/draw/polygonfill.pygithub.com疑问:
for i in range(len(polys)): for j in range(len(polys[i])): ys.append((i,j,polys[i][j][1])) ys = np.array(ys)
转换成一维数组还是转换成适合pandas处理的数据结构?
polys[i][j][1])代表什么?
cur = scan(polys, idx, ys[:,2], st, y, cur, buf)
一列扫描吗?
ImagePy_Learn学习系列
土盐:ImagePy_Learn | 图形学绘制代码学习:coredrawfill.py
土盐:ImagePy_Learn | 图形学绘制代码学习:paint.py
详解如下:
round((p1[0]+k*p2[0])/(1+k),4)
参考原文链接:Python round() 函数
np.sort(rs)
参考原文链接:np.sort()函数的作用 - Vaxue的博客 - CSDN博客
plg[:-1]
X[:,0]是numpy中数组的一种写法,表示对一个二维数组,取该二维数组第一维中的所有数据,第二维中取第0个数据,直观来说,X[:,0]就是取所有行的第0个数据, X[:,-1] 就是取所有行的最后一个数据。
import numpy as np
a=np.random.rand(5)
print(a)
[ 0.64061262 0.8451399 0.965673 0.89256687 0.48518743]print(a[-1]) ###取最后一个元素
[0.48518743]print(a[:-1]) ### 除了最后一个取全部
[ 0.64061262 0.8451399 0.965673 0.89256687]print(a[::-1]) ### 取从后向前(相反)的元素
[ 0.48518743 0.89256687 0.965673 0.8451399 0.64061262]print(a[2::-1]) ### 取从下标为2的元素翻转读取
[ 0.965673 0.8451399 0.64061262]
参考原文链接:python中[-1]、[:-1]、[::-1]、[n::-1]使用方法 - qq_21840201的博客 - CSDN博客
python p[:0]与p[:1]的区别
img.shape[:2]
img.shape[:2] 取彩色图片的高、宽,如果img.shape[:3] 取彩色图片的高、宽、通道
1:一般的数组如:【22,33】 shape是(2,):他表示他是一个一维数组,数组中有两个元素;注意他和shape(2,1)的区别,他两个不一样。
2:[[22],[33]] 他的shape是(2,1),表示二维数组,每行有一个元素
3:[[22,33]] shape是(1,2) 他表示一个二维数组,每行有两个元素
image.shape[0], 图片垂直尺寸
image.shape[1], 图片水平尺寸
image.shape[2], 图片通道数
参考原文链接:shape 函数,以及shape(2,)和shape(2,1)区别
区别 image.shape[0],image.shape[1],image.shape[2]
st = np.argsort(ys[:,2])
numpy.argsort(a, axis=-1, kind=’quicksort’, order=None)
功能:
将矩阵a按照axis排序,并返回排序后的下标
参数:
a:输入矩阵, axis:需要排序的维度
返回值:
输出排序后的下标
参考原文链接:numpy中实用但不常见的方法(3)np.argsort - cetrol_chen的博客 - CSDN博客
bot,top = np.clip([int(ys[:,2].min()-1),int(ys[:,2].max()+2)], 0, shape[0])
将[int(ys[:,2].min()-1),int(ys[:,2].max()+2)]范围外的数强制转化为[0, shape[0]]范围内的数
def clip(a, a_min, a_max, out=None):
将数组a中的所有数限定到范围a_min和a_max中,即az中所有比a_min小的数都会强制变为a_min,a中所有比a_max大的数都会强制变为a_max.- 其中
a_min
和a_max
可以为一个和a
一样大小的数组(列表也可以,只要是类似数组的结构就是可行的),则数组中相应位置的元素
进行比较。 out
是可选项,表示把强制截取后的结果放到这个数组中,但是out
中的数组必须和a
形状一样
参考原文链接:np.clip截取函数 - cloud&ken - 博客园
python中numpy模块下的np.clip()的用法 - IT届的小学生 - CSDN博客
idx = ys[:,:2].astype(np.int16)
使用方法:
- df.astype('数据类型') #改变整个df的数据类型
- df['列名'].astype('数据类型') #仅改变某一列的数据类型
num=num.astype('str')#将整个dataframe都转换为str类型
参考原文链接:python强制类型转换astype - weixin_42036641的博客 - CSDN博客
ys.append((i,j,polys[i][j][1]))
numpy.append(arr, values, axis=None):
简答来说,就是arr和values会重新组合成一个新的数组,做为返回值。而axis是一个可选的值
当axis无定义时,是横向加成,返回总是为一维数组!
Examples
--------
>>> np.append([1, 2, 3], [[4, 5, 6], [7, 8, 9]])
array([1, 2, 3, 4, 5, 6, 7, 8, 9])
numpu.append(arr,values,axis=None)
将values插入到目标arr的最后。
注意,这里values跟arr应该为相同维度的向量
参考原文链接:numpy的numpy.delete()/insert()/append()函数 - 开贰锤 - CSDN博客
对numpy.append()里的axis的用法详解_python_脚本之家
ys = np.array(ys)
参考原文链接:python中数组(numpy.array)的基本操作 - fu6543210的博客 - CSDN博客
np.array(rst).T
转置函数.T,将原shape为(n,m)的数组转置为(m,n),一维数组转置不变
参考原文链接:python数据分析(3)--numpy数组形状转换.T/.reshape()/.resize() - weixin_42695959的博客 - CSDN博客
rst.extend([(x,y) for x in range(max(x1,o[0]), min(x2, shape[2]))])
1. 列表可包含任何数据类型的元素,单个列表中的元素无须全为同一类型。
2. append()
方法向列表的尾部添加一个新的元素。只接受一个参数。
3. extend()
方法只接受一个列表作为参数,并将该参数的每个元素都添加到原有的列表中。
数组拼接方法一
思路:首先将数组转成列表,然后利用列表的拼接函数append()、extend()等进行拼接处理,最后将列表转成数组。
示例1:
>>> import numpy as np
>>> a=np.array([1,2,5])
>>> b=np.array([10,12,15])
>>> a_list=list(a)
>>> b_list=list(b)
>>> a_list.extend(b_list)
>>> a_list
[1, 2, 5, 10, 12, 15]
>>> a=np.array(a_list)
>>> a
array([ 1, 2, 5, 10, 12, 15])
该方法只适用于简单的一维数组拼接,由于转换过程很耗时间,对于大量数据的拼接一般不建议使用。
参考原文链接:numpy数组拼接方法介绍 - zyl1042635242的专栏 - CSDN博客
python中的append的用法 - m0_37870649的博客 - CSDN博客
for i in zip(rs[::2],rs[1::2])
参考原文链接:Python zip() 函数 | 菜鸟教程
源码快查
# -*- coding: utf-8 -*-
"""
Created on Mon Nov 14 17:40:41 2016
@author: yxl
"""
from __future__ import absolute_import
import numpy as npdef f(p1,p2,y):if abs(p1[1]-y) > abs(p2[1]-y):p1,p2 = p2,p1k =1.0* (p1[1]-y)/(y-p2[1])return round((p1[0]+k*p2[0])/(1+k),4)def scan(polys, idx, ys, st, y, cur, buf):while cur<len(idx) and ys[st[cur]]<=y:c = idx[st[cur]]poly = polys[c[0]]for i in (c[0], (c[1]-1)%len(poly)), tuple(c):if i in buf:buf.remove(i)else: buf.append(i)cur += 1return curdef roots(polys, buf, y):rs = []for i in buf:poly = polys[i[0]]i1,i2 = i, (i[0],(i[1]+1)%len(poly))rs.append(f(poly[i1[1]], poly[i2[1]],y))return np.sort(rs)def fill(plgs, img, color = 1, o=(0,0)):polys = [np.array(plg[:-1])-0.5 for plg in plgs]shape = img.shape[:2]ys = []for i in range(len(polys)):for j in range(len(polys[i])):ys.append((i,j,polys[i][j][1]))ys = np.array(ys)st = np.argsort(ys[:,2])buf, rst, cur = [], [], 0bot,top = np.clip([int(ys[:,2].min()-1),int(ys[:,2].max()+2)], 0, shape[0])idx = ys[:,:2].astype(np.int16)for y in range(bot, top):cur = scan(polys, idx, ys[:,2], st, y, cur, buf)rs = roots(polys, buf, y)for i in zip(rs[::2],rs[1::2]):x1, x2 = int(np.ceil(i[0])), int(np.floor(i[1])+2)x1, x2 = max(x1,0), min(x2, shape[1])if x1 >= shape[1] or x2 < 0: continue#rst.extend([(x,y) for x in range(max(x1,o[0]), min(x2, shape[2]))])img[y,x1:x2] = colorreturn np.array(rst).Tif __name__ == '__main__':import matplotlib.pyplot as pltfrom time import time# pg.shape = (1,4,2)pg = np.array([[(-300,-100),(1100,100),(400,1300),(100,100)]])# img.shape = (1000, 500)img = np.zeros((1000, 500))a = time()rc= fill(pg, img)print(time() - a)plt.imshow(img, interpolation='nearest',cmap='gray')plt.show()print("Done!")