以前、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#で使えるのは大きなメリットかなと思います。

OpenCVSharpの公式サイトに記載されているので、ご存じかもしれませんが。
< デバッグ中にIplImageの中を確認する方法をメモしておきます。

DebuggerVisualizer - opencvsharp http://code.google.com/p/opencvsharp/wiki/DebuggerVisualizer

導入方法

OpenCVSharpの中に含まれているdllの中に

OpenCvSharp.DebuggerVisualizers.dll

があります。
それを、My DocumentのVisual StudioのVisualizersというフォルダにコピーします。

VistaでVisual Studio2010の例ですと。
C:\Users\XXX\Documents\Visual Studio 2010\Visualizers
になります。


使い方

デバッグ中にIplImageの変数にフォーカスを当てると、虫メガネのマークが表示されるので
それをクリックすると現在の状況の画像が表示されます。

Log-Polar変換なのですが、霊長類の網膜のモデルらしいです。
中心部は解像度が高いのですが、周辺部は低いという特性らしいです。

以下のような式で変換をします。(極座標変換でのrにlogをとったものです。)
logpolar.png


ですが、今まで行った回転のときのように、どの変換先の座標は元画像のどの位置を参照するかと考えます。
すなわち以下の逆変換を使います。
logpolar2.png



ソース


OpenCVのやりかたを真似したため、一部のみ抜粋です。
bmpが入力画像、lpcが出力画像です。
また、Mはformから入力された値を使用しました。256x256だと40くらいがよさそうです。
BiLinearInterpolationは以前の補間のさいに使用したものです。

画像を回転させる際の画素を補間するコード | 詠み人知らずの備忘録


Bitmap lpc = new Bitmap(bmp.Width, bmp.Height);

int cx = lpc.Width / 2;
int cy = lpc.Height / 2;

double M = Convert.ToDouble(textBox1.Text);

for (int i = 0; i < lpc.Width; i++)
{
    for (int j = 0; j < lpc.Height; j++)
    {
        double r = Math.Exp((double)i / (double)M);
        double x = r * Math.Cos(2 * Math.PI * j / lpc.Height) + cx;
        double y = r * Math.Sin(2 * Math.PI * j / lpc.Height) + cy;
        
        if (0 < x && x < bmp.Width - 1 && 0 < y && y < bmp.Height - 1)
        {
            Color bmpCol = BiLinearInterpolation(x, y, bmp);
            lpc.SetPixel(i, j, bmpCol);
        }

    }
}



結果

変換した結果、(x,y)と(rho,phi)の関係がどのような対応になるのかは、下記のサイトがイメージがつきやすいと思います。
Log polar transform - Rhea



※クリックで拡大します。

【元画像】
Lenna

【変換画像】
Lenna_log.png

【元画像】
Lenna_90.png

【変換画像】
Lenna_log90.png



画像の回転が、変換後の画像の下への移動としてあらわされています。
この考え方を、位相限定相関法(POC)と供に使用すると、角度のズレを判別できるためより便利な手法となります。(RIPOCという手法らしいです。)

位相限定相関法(POC) - スズメレンダラー・クマ将棋の開発日記

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

詠み人知らず

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

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

カレンダー
08 | 2017/09 | 10
- - - - - 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
最新記事
タグクラウドとサーチ

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