LoginSignup
18
13

More than 3 years have passed since last update.

numpy配列とctypes配列の相互変換

Last updated at Posted at 2019-06-22

multiprocessingで生成したプロセス同士でndarray配列を共有する必要があったのでメモ

ctypesの変数については以下の記事を参照
https://qiita.com/maiueo/items/b2093ba78cde988bb111

ライブラリの読み込み

import ctypes
import numpy as np

ndarray -> ctypes

n = np.zeros((3, 4)).astype(np.uint8)  # ndarray型の3x4の配列を生成
n_h, n_w = n.shape  # nのサイズを取得
c = n.ctypes.data_as(ctypes.POINTER((ctypes.c_uint8 * n_w) * n_h)).contents  # ctypesの3x4の配列へと変換

np.uint8, ctypes.c_uint8の部分は配列に用いる型の指定
ncはともに同じアドレスを参照しているので、片方を書き換えるともう片方にも書き換えが反映されます。
n.ctypes.data_asnの配列の先頭ポインタを引数で指定したctypesのポインタにキャストしたものを返します。

ctypes -> ndarray

c = ((ctypes.c_uint8 * 4) * 3)()  # ctypesの3x4の配列を生成
n = np.ctypeslib.as_array(c)  # ndarray型の3x4の配列へと変換

ctypes.c_uint8の部分は配列に用いる型の指定
こちらも、cnはともに同じアドレスを参照しているので、片方を書き換えるともう片方にも書き換えが反映されます。

サンプルプログラム

cv2で読み込んだ画像(ndarray型)をctypes型に変換し、それをまたndarray型に戻すプログラムです。
画像ファイルのパスの箇所を適宜変更してください。

import ctypes
import numpy as np
import cv2

if __name__ == '__main__':
    # 適当な画像からndarrayの生成
    input_img = cv2.imread("画像ファイルのパス")

    # uint8に変換
    input_img = input_img.astype(np.uint8)

    # input_imgのサイズ、チャンネル数を取得
    img_h, img_w, img_ch = input_img.shape

    # input_imgをctypesの配列に変換
    input_img_c = input_img.ctypes.data_as(ctypes.POINTER(((ctypes.c_uint8 * img_ch) * img_w) * img_h)).contents

    # ctypesの配列からndarrayを生成
    output_img = np.ctypeslib.as_array(input_img_c)

    # プレビュー
    cv2.imshow("input", input_img)
    cv2.imshow("output", output_img)
    cv2.waitKey(0)

参考

https://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.ctypes.html
https://docs.scipy.org/doc/numpy-1.15.1/reference/routines.ctypeslib.html
https://stackoverflow.com/questions/3195660/how-to-use-numpy-array-with-ctypes
https://stackoverflow.com/questions/4355524/getting-data-from-ctypes-array-into-numpy

18
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
13