日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > python >内容正文

python

python中噪音是什么意思_Perlin噪声和Python的ctypes

發(fā)布時(shí)間:2024/3/12 python 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python中噪音是什么意思_Perlin噪声和Python的ctypes 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

最近在知乎上看了一篇關(guān)于用C++加速Python的短文,受益匪淺。同時(shí)也受到啟發(fā),撰寫此文作為以后的參考。

作為Python的用戶經(jīng)常碰到的一個(gè)問題就是速度太慢,一般來說速度下降的一個(gè)主要原因是來自多重的for循環(huán)。如何給現(xiàn)有的Python代碼加速其實(shí)是Python用戶的一門必修課。比較熟悉numpy的用戶,可以熟練地寫成矩陣化操作,這樣可以大大加速運(yùn)行的效率。這和MATLAB里多用矩陣操作而少用for循環(huán)是一個(gè)道理。但往往我們中的大多數(shù)并沒有高超的numpy技巧。即便是有,Python代碼的閱讀性可能反而會(huì)下降。就算退一步講,寫成了比較好的numpy的代碼也未必會(huì)比C/C++的代碼快。在不放棄Python語(yǔ)言的前提下,怎么用C語(yǔ)言來提速呢?方法有很多,前面的所指的短文已經(jīng)給出了一個(gè)答案。這里我再用一個(gè)例子做一個(gè)簡(jiǎn)單的說明,希望對(duì)大家有所幫助。首先代碼都可以取到,https://github.com/yanfeit/PerlinNoise?github.com

關(guān)于Perlin噪聲,我就不詳細(xì)介紹。簡(jiǎn)單地說來,Perlin噪聲具有光滑性,自然性和隨機(jī)性的特點(diǎn)。感興趣的讀者可以找到很多相關(guān)資料,在這里我推薦兩個(gè),pvigier的GitHub site和Adrian's 的博客。Pvigier的Perlin噪聲是用numpy來實(shí)現(xiàn)的,讀者如果對(duì)自己numpy的技巧深感自信,可以去閱讀一下他寫的代碼。閱讀他的代碼之后,我們可以給自己兩個(gè)問題:我是否可以寫出這樣高度矩陣化操作的numpy代碼?

是否我們遇到的所用問題都可以用numpy矩陣化的操作來解決?

我想讀者心中可能也會(huì)犯嘀咕,確實(shí),高度矩陣化的操作需要程序員有高超的numpy技巧。反正我自愧不如,認(rèn)為我很難寫出那樣漂亮的代碼。我們?cè)賮砜纯碅drian的博客,這是篇博客文中的上乘之作, 是關(guān)于Perlin噪聲的一個(gè)詳細(xì)介紹,配合C#來實(shí)現(xiàn)。我想大多數(shù)讀者可能和我一樣,對(duì)寫成for循環(huán)的形式感到極度舒適。而閱讀這樣的代碼我想讀者們也是駕輕就熟吧。所以我首先制作了一個(gè)Perlin噪聲的C++代碼(其實(shí)只用到了C的成分),之后我們會(huì)使用ctypes來調(diào)用動(dòng)態(tài)鏈接庫(kù)的代碼。

創(chuàng)建動(dòng)態(tài)鏈接庫(kù)

$ mkdir build

$ cd build

$ cmake ..

$ make

$ mv ./lib/libperlinNoise.dylib ../python # Move library to the python folder.

$ cd ../python

$ python caltime.py # compare the time usage of numpy and C code.

為了快速測(cè)試一下效果,讀者可以嘗試執(zhí)行以上的代碼。

用了make之后我們會(huì)在/build/lib目錄下得到一個(gè)libperlinNoise.dylib的動(dòng)態(tài)鏈接庫(kù)文件,在這個(gè)庫(kù)里面我們可以調(diào)用兩個(gè)函數(shù)。它們的接口如下所示,

// 你可以在./lib/PerlinNoise.h的文件中找到相應(yīng)代碼。// 純粹為了解釋一下Float#ifndef PRECISION#define PRECISION 1#endif#if PRECISION==1typedef float Float;

#elsetypedef double Float;

#endif// .....省略很多代碼......// lattice 是指生成梯度所在的格子的大小,x,y,z當(dāng)然指的是方向// res 是指resolution,解析度(像素)。這里我與Pvigier的定義是不同的。Float* perlinNoise3D(int lattice_x, int lattice_y, int lattice_z,

int res_x, int res_y, int res_z);

Float* perlinNoise2D(int lattice_x, int lattice_y, int res_x, int res_y);

兩個(gè)函數(shù)返回的是指向Float的指針,我選用了單精度的浮點(diǎn)數(shù)也就是float。這里面有個(gè)需要注意的地方,函數(shù)切記不要返回指向一個(gè)超過二維數(shù)組的指針,其實(shí)根本就沒有這樣的定義,具體請(qǐng)看這個(gè)帖子。有了libperlinNoise.dylib這個(gè)動(dòng)態(tài)鏈接庫(kù)之后,剩下的任務(wù)就交給Python了。以下是我的代碼的一部分(借鑒了Pvigier的代碼,在./python/cppnoise.py中可以找到相應(yīng)的代碼),

# 我們所采用加速的方法,ctypes是build-in package

import ctypes

# 因?yàn)槲覀円祷刂羔?#xff0c;我覺得調(diào)用numpy下的這個(gè)包是我找到的比較簡(jiǎn)單可行的方法

from numpy.ctypeslib import ndpointer

# ...省略...其余的包的調(diào)用....

def octavePerlin2d(lattice, res, octaves = 1, persistence=0.5):

# pass the dynamic library

lib = ctypes.CDLL('./libperlinNoise.dylib')

# get the 2d Perlin noise function

perlinNoise2D = lib.perlinNoise2D

# Need specify the types of the argument for function perlinNoise2D

perlinNoise2D.argtypes = (ctypes.c_int, ctypes.c_int,

ctypes.c_int, ctypes.c_int)

# This note is extremely useful to understand how to return a 2d array!

# https://stackoverflow.com/questions/43013870/

# how-to-make-c-return-2d-array-to-python?noredirect=1&lq=1

# We can never pass a 2d array, therefore return 1d array in a C function

perlinNoise2D.restype = ndpointer(dtype=ctypes.c_float,

shape = (res[0], res[1]))

noise = np.zeros(res)

frequency = 1

amplitude = 1

for _ in range(octaves):

temp = perlinNoise2D(ctypes.c_int(frequency*lattice[1]),

ctypes.c_int(frequency*lattice[0]),

ctypes.c_int(res[1]),

ctypes.c_int(res[0]) )

noise += amplitude * temp

frequency *= 2

amplitude *= persistence

return noise

相比于木盞的函數(shù),我這里相對(duì)來說復(fù)雜一點(diǎn)點(diǎn)。我們需要注意的是,我們得告訴函數(shù)傳入的參數(shù)的類型和返回的類型和大小,這點(diǎn)至關(guān)重要。

# 讀取動(dòng)態(tài)鏈接庫(kù),

lib = ctypes.CDLL('./libperlinNoise.dylib')

# 從句柄中拿到PerlinNoise2D的函數(shù)

perlinNoise2D = lib.perlinNoise2D

# 告訴函數(shù)傳入?yún)?shù)的個(gè)數(shù)和類型

perlinNoise2D.argtypes = (ctypes.c_int, ctypes.c_int,

ctypes.c_int, ctypes.c_int)

# 告訴函數(shù)返回的類型,是c_float。shape是optinal的。

perlinNoise2D.restype = ndpointer(dtype=ctypes.c_float,

shape = (res[0], res[1]))

# 調(diào)用的方法非常簡(jiǎn)單。

temp = perlinNoise2D(ctypes.c_int(frequency*lattice[1]),

ctypes.c_int(frequency*lattice[0]),

ctypes.c_int(res[1]),

ctypes.c_int(res[0]) )

在Python中調(diào)用動(dòng)態(tài)鏈接庫(kù)后得到的加速效果(當(dāng)然我在C++用了單精度的float),讀者可以自行修改成雙精度去測(cè)試一下。

$ python caltime.py

2D noise, numpy time consuming: 0.08261830806732177

3D noise, numpy time consuming: 4.525643992424011

2D noise, cpp time consuming: 0.007184123992919922

3D noise, cpp time consuming: 0.1645211935043335

我們可以發(fā)現(xiàn)C語(yǔ)言的代碼可以說快了將近10倍以上。

最后上個(gè)圖,以饗讀者。

總結(jié)

以上是生活随笔為你收集整理的python中噪音是什么意思_Perlin噪声和Python的ctypes的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。