Category
homebrewで導入したpyenvにpythonを導入しようとした際に、
うまくいかなかったことがあったのでメモ

~ $ pyenv install 2.7.8
Downloading Python-2.7.8.tgz...
-> https://yyuu.github.io/pythons/74d70b914da4487aa1d97222b29e9554d042f825f26cb2b93abd20fdda56b557
Installing Python-2.7.8...
patching file ./Lib/site.py
ERROR: The Python zlib extension was not compiled. Missing the zlib?

Please consult to the Wiki page to fix the problem.
https://github.com/yyuu/pyenv/wiki/Common-build-problems


BUILD FAILED (OS X 10.11.1 using python-build 20150818)


こちらのページにも同様の現象が報告、解決策が提示されていました。
Can't compile on El Capitan #448

結論としては、下記のツールが入っていなかっただけでした。
~ $ xcode-select --install
xcode-select: note: install requested for command line developer tools


再度、installを実施してみたところ。
~ $ pyenv install 2.7.8
Downloading Python-2.7.8.tgz...
-> https://yyuu.github.io/pythons/74d70b914da4487aa1d97222b29e9554d042f825f26cb2b93abd20fdda56b557
Installing Python-2.7.8...
patching file ./Lib/site.py
Installing pip from https://bootstrap.pypa.io/get-pip.py...
Installed Python-2.7.8 to /Users/tki/.pyenv/versions/2.7.8
うまくいきました。
以前、IronPythonでimportができない例を書きました。

C#でIronPythonと連携する際にnumpyがimportできない | 詠み人知らずの備忘録



上記の対応を行うことで、DLLがロードできるため
numpyやwaveなどをimportできるようにはなったのですが、Scipyだけは下記のようにエラーが出てだめでした。

'module' object has no attribute '_getframe'

Scipy_error.png

どうやらコンソールからIronPythonを起動する際にScipyを使用するに、 -X:Frames と引数を渡していることに関係あるみたいです。

結果としては、Pythonのエンジンを起動する際に下記のようにオプションを設定して起動するように行えばいいようです。

var options = new Dictionary();
options["Frames"] = true;
options["FullFrames"] = true;
ScriptEngine engine = Python.CreateEngine(options);

※1行目と5行目がなぜかおかしくなっています。
 ただしくは、
 var options = new Dictionary<string, object>();
 です。



また、Python側でも以下のpathを追加していないとno moduleのエラーがでます。
特に、Scipyでは4行目の定義も必要のようです。
sys.path.append(r'C:\Program Files\IronPython 2.7')
sys.path.append(r'C:\Program Files\IronPython 2.7\DLLs')
sys.path.append(r'C:\Program Files\IronPython 2.7\Lib')
sys.path.append(r'C:\Program Files\IronPython 2.7\Lib\site-packages')



C#にはどうやら音声ファイルを簡単に読み込む手段がないようで、
じゃあPythonに任せればいいのでは?


。。。ということで今回は、C#とIronPythonで音声ファイルのデータを読み込みます。


Pythonの音声ファイルの取得はこちらを参考にしました。
漫ろ草 SozoroGusa: pythonでwaveファイル(2)



ソース

C#側
using System;
using System.Collections.Generic;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using IronPython.Hosting;           // for IronPython
using Microsoft.Scripting.Hosting;  // for IronPython

namespace LoadWave
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void 開くOToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //「ファイルの種類」を設定
            openFileDialog1.Filter = "音声ファイル(WAV)|*.wav;|すべてのファイル(*.*)|*.*";
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                // Scipyを起動するためのオプション設定
                var options = new Dictionary();
                options["Frames"] = true;
                options["FullFrames"] = true;

                ScriptEngine engine = Python.CreateEngine(options);

                ScriptSource script = engine.CreateScriptSourceFromFile("sample.py");
                ScriptScope scope = engine.CreateScope();
                
                // 選択したwavファイルをPythonに渡す値として設定
                scope.SetVariable("filename", openFileDialog1.FileName);

                // IronPythonを実行
                script.Execute(scope);

                // 処理した音声データを取得
                var audio = scope.GetVariable("audio");
            }
        }
    }
}



C#のopenFileDialogで、選択した音声ファイルをIronPythonに渡してfilenameという変数で使用しています。
// 選択したwavファイルをPythonに渡す値として設定
scope.SetVariable("filename", openFileDialog1.FileName);



IronPythonで取得した音声データ(audio)をC#側に返しています。
// 処理した音声データを取得
var audio = scope.GetVariable("audio");



IronPython側
#-*- coding: utf-8 -*-
import sys
sys.path.append(r'C:\Program Files\IronPython 2.7')
sys.path.append(r'C:\Program Files\IronPython 2.7\DLLs')
sys.path.append(r'C:\Program Files\IronPython 2.7\Lib')
sys.path.append(r'C:\Program Files\IronPython 2.7\Lib\site-packages')

import clr
clr.AddReference('mtrand.dll')

import wave
import struct

wf = wave.open(filename, "rb")

#オーディオチャンネル数(モノラルなら1、ステレオなら2)
nchannels=wf.getnchannels()
#サンプルサイズ(バイト)
sampwidth=wf.getsampwidth()
#サンプリングレート
framerate=wf.getframerate()
#オーディオフレーム数
nframes=wf.getnframes()
#オーディオフレーム(リストオブジェクト)
frames=wf.readframes(nframes)
wf.close()

audio = struct.unpack("%dh" %nframes*nchannels, frames)



C#で配列を受け取る際にどのようにすればいいのか、特に記載はなかったのですが。
上記のようで問題ないようです。



ちなみに、正弦波の音声データを読み込んで、取得したデータを表示したものが下記のグラフです。

sin.png


C#からIronPythonを呼び出すために、調べていた際にはまったことをメモ。

簡単なスクリプトやメソッドなら呼び出せるのですがimport numpyやimport waveなどを使用すると
下記のようなエラーが・・・






メッセージ内容を見ると

IronPython.Runtime.Exceptions.ImportException はハンドルされませんでした。
Message=No module named numpy


とのこと、

DLLのロードができていないようなのですが、
他のサイトでは連携の際に上記現象の記載がない方もいらっしゃるようでこのへんは謎です。



ソース

エラーの原因は、IronPythonでロードができていないようです。
強調された箇所を追加することによって実行ができるようになりました。
#もっといい手法あるような気がしますが、調べても出てこないので。。。

ソースは以下のようになります。

Python
#-*- coding: utf-8 -*-
import sys
sys.path.append(r'C:\Program Files\IronPython 2.7')
sys.path.append(r'C:\Program Files\IronPython 2.7\DLLs')
sys.path.append(r'C:\Program Files\IronPython 2.7\Lib')
sys.path.append(r'C:\Program Files\IronPython 2.7\Lib\site-packages')

import clr
clr.AddReference('mtrand.dll')

import numpy as np

result = np.sin(input)



C#
次にC#です。
以下の2つのDLLを参照の追加を行い。
  • IronPython.dll
  • Microsoft.Scripting.dll


その後、usingの追加を行ってください。
  • using IronPython.Hosting;
  • using Microsoft.Scripting.Hosting;
// Pythonスクリプト実行エンジン
ScriptEngine engine = Python.CreateEngine();

// 実行するPythonのソースを指定
ScriptSource source = engine.CreateScriptSourceFromFile("../../sample.py");

// 実行エンジンに渡す値を設定する
ScriptScope scope = engine.CreateScope();

// Pythonに渡す値を設定(inputという変数に40を設定)
scope.SetVariable("input", 40);

// 実行
source.Execute(scope);

// Pythonの実行結果を取得
double result = scope.GetVariable("result");




IronPythonでの計算、C#側で計算結果の受け取りができることを確認しました。
もっと良い方法があるのかもしれませんが、この辺であきらめましたorz


若干ロードがあるせいか遅い気がしますが、IronPythonのnumpyなどのライブラリがC#で使えるのは大きなメリットかなと思います。

最近IronPythonに興味をもちまして。
調べたことのメモを


・利点
  1. .Netが使用できる
  2. numpyなどのライブラリが使用できる
  3. Visual Studio(expressじゃないほう)で開発ができる

Pythonはeclipseでも開発できますが

IronPythonのインストールからVisual Studio(expressじゃないほう)で使用できるようになるまでの準備はこちらで
Visual Studio 2010のインストール


VSで生成されるプログラムは以下のようになりました。
実行すれば何もないWindowが表示されます。

import clr
clr.AddReference('System.Drawing')
clr.AddReference('System.Windows.Forms')

from System.Drawing import *
from System.Windows.Forms import *

class MyForm(Form):
    def __init__(self):
        # Create child controls and initialize form
        pass


Application.EnableVisualStyles()
Application.SetCompatibleTextRenderingDefault(False)

form = MyForm()
Application.Run(form)



ButtonやLabelをGUI上でペタペタ貼ってUIを作成する機能があれば楽なのですが。。。


IronPython用(?)のnumpyをインストールしたい場合は下記のURLの
3.) ironpkg
4.) scipy
を実施すれば問題なしです
https://www.enthought.com/repo/.iron/

FC2カウンター
プロフィール

詠み人知らず

Author:詠み人知らず
プログラム好きな名もなき凡人がお送りしています。(得意とは言っていない
最近の興味はPython、C#、Matlab(Octave)、画像処理、AR(拡張現実)、統計などなど・・・

気分で思いついたことを書くため話題に一貫性がないかもしれません。

カレンダー
07 | 2017/08 | 09
- - 1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31 - -
最新記事
タグクラウドとサーチ

カテゴリ
最新コメント
最新トラックバック
月別アーカイブ