0
点赞
收藏
分享

微信扫一扫

ImagePy_Learn | 图形学绘制代码学习:core\draw\polygonfill.py




最近在学图形学绘制,想到了ImagePy框架的ROI涂抹交互很方便,于是啃起了绘制代码。

这里主要对ImagePy中一个填充工具进行难点讲解。

让我们好好学习Python中的图形学绘制吧。

例子代码来源

​​

​​

​​
# -*- coding: utf-8 -*-
"""
Created on Mon Nov 14 17:40:41 2016
@author: yxl
"""
from __future__ import absolute_import
import numpy as np

def f(p1,p2,y):
if abs(p1[1]-y) > abs(p2[1]-y):p1,p2 = p2,p1
k =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 += 1
return cur

def 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 = [], [], 0
bot,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] = color

return np.array(rst).T

if __name__ == '__main__':
import matplotlib.pyplot as plt
from 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!")


疑问:

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 | 图形学绘制代码学习:core\draw\fill.py​​

​​土盐:ImagePy_Learn | 图形学绘制代码学习:paint.py​​


详解如下:

round((p1[0]+k*p2[0])/(1+k),4)

ImagePy_Learn | 图形学绘制代码学习:core\draw\polygonfill.py_python


np.sort(rs)

ImagePy_Learn | 图形学绘制代码学习:core\draw\polygonfill.py_python_02


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]


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], 图片通道数


st = np.argsort(ys[:,2])

numpy.argsort(a, axis=-1, kind=’quicksort’, order=None)

功能: 将矩阵a按照axis排序,并返回排序后的下标

参数: a:输入矩阵, axis:需要排序的维度

返回值: 输出排序后的下标

ImagePy_Learn | 图形学绘制代码学习:core\draw\polygonfill.py_python_03


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形状一样

ImagePy_Learn | 图形学绘制代码学习:core\draw\polygonfill.py_csdn博客_04

参考原文链接:​​np.clip截取函数 - cloud&ken​​

​​python中numpy模块下的np.clip()的用法 - IT届的小学生​​


idx = ys[:,:2].astype(np.int16)

使用方法:


  • df.astype('数据类型') #改变整个df的数据类型
  • df['列名'].astype('数据类型') #仅改变某一列的数据类型

ImagePy_Learn | 图形学绘制代码学习:core\draw\polygonfill.py_csdn博客_05

num=num.astype('str')#将整个dataframe都转换为str类型

参考原文链接:​​python强制类型转换astype - weixin_42036641的博客​​


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应该为相同维度的向量

ImagePy_Learn | 图形学绘制代码学习:core\draw\polygonfill.py_imagepy_06

参考原文链接:​​numpy的numpy.delete()/insert()/append()函数 - 开贰锤​​


ys = np.array(ys)

ImagePy_Learn | 图形学绘制代码学习:core\draw\polygonfill.py_python_07

参考原文链接:​​python中数组(numpy.array)的基本操作 - fu6543210的博客

np.array(rst).T

转置函数.T,将原shape为(n,m)的数组转置为(m,n),一维数组转置不变

参考原文链接:​​python数据分析(3)--numpy数组形状转换.T/.reshape()/.resize() - weixin_42695959的博客博客​​


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的专栏 ​​

​​python中的append的用法 - m0_37870649的博客​​


for i in zip(rs[::2],rs[1::2])

ImagePy_Learn | 图形学绘制代码学习:core\draw\polygonfill.py_csdn博客_08

参考原文链接:​​Python​​ zip() 函数 | 菜鸟教程






举报

相关推荐

0 条评论