nprogram’s blog

気ままに、プログラミングのトピックについて書いていきます

UnicodeからUTF-8に変換する方法 [C++] [MFC]

はじめに

UnicodeからUTF-8に変換する方法を調べたので、記録します。

Convert Unicode (utf-16) CStringW to utf-8 CStringA

CStringA ConvertUnicodeToUTF8(const CStringW& uni)
{
    if (uni.IsEmpty()) return ""; // nothing to do
    CStringA utf8;
    int cc=0;
    // get length (cc) of the new multibyte string excluding the \0 terminator first
    if ((cc = WideCharToMultiByte(CP_UTF8, 0, uni, -1, NULL, 0, 0, 0) - 1) > 0)
    { 
        // convert
        char *buf = utf8.GetBuffer(cc);
        if (buf) WideCharToMultiByte(CP_UTF8, 0, uni, -1, buf, cc, 0, 0);
        utf8.ReleaseBuffer();
    }
    return utf8;
}

Convert utf-8 CStringA to Unicode (utf-16) CStringW

CStringW ConvertUTF8ToUnicode(const CStringA& utf8)
{
    if (utf8.IsEmpty()) return L""; // nothing to do
    CStringW uni;
    int cc=0;
    // get length (cc) of the new widechar excluding the \0 terminator first
    if ((cc = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0) - 1) > 0)
    { 
        // convert
        wchar_t *buf = uni.GetBuffer(cc);
        if (buf) MultiByteToWideChar(CP_UTF8, 0, utf8, -1, buf, cc);
        uni.ReleaseBuffer();
    }
    return uni;
}

参考リンク

Convert Unicode (utf-16) CString to utf-8 and reverse

仮説検証学習

はじめに

仮説検証を学習していきたいと思います。

(1) どうなりたいのか(狙う結果)

(2) 何によって確かめるのか(指標)?

(3) そのために何をするのか?

(4) なぜ狙う効果が得られるのか?

ポイント

  • 仮説検証の内容は、具体的な数値にしましょう
  • 各項目で、内容が一致しない事態が発生しないようにしましょう

TensorFlow Object Detection APIをWindowsで使ってみた

はじめに

以下のサイトを見てTensorFlow Object Detection APIをWindowsで使ってみようと思います。

TensorFlow Object Detection APIは、TensorFlowを利用して、画像に写っている物体を検出するためのフレームワークです。

インストール手順・実行方法は、Samurai Blog様のブログが素晴らしい記事を書いていますので、そちらを参考にするといいと思います。

(ただし、注意点にも記載しているTensorFlowのバージョンには注意)

https://www.sejuku.net/blog/56695

注意点

TensorFlowのバージョンはv1.12以上である必要があります。かなり新しいTensorFlowバージョンでなければ動かないため、注意が必要です。(2019年4月28日時点)

古いTensorflow Versionでは、以下のように正しく動きません。

ImportError                               Traceback (most recent call last)
<ipython-input-1-34f5cdda911a> in <module>
     18 
     19 if StrictVersion(tf.__version__) < StrictVersion('1.12.0'):
---> 20   raise ImportError('Please upgrade your TensorFlow installation to v1.12.*.')

ImportError: Please upgrade your TensorFlow installation to v1.12.*.

本記事では

以下の記事を見ながら作業を進めていきます。

TensorFlow Object Detection APIをWindowsで使ってみた - Qiita

Protobufのコンパイルができない問題については、以下のサイトに解決策が書かれています。

python - protoc object_detection/protos/*.proto: No such file or directory - Stack Overflow

for /f %i in ('dir /b object_detection\protos\*.proto') do protoc object_detection\protos\%i --python_out=.
(tensorflow_gpu) C:\Users\uv2ut\Jupyter_Project_GPU\TensorFlow_Object_Detection_API\models-master\research>python object_detection/builders/model_builder_test.py
......C:\Users\uv2ut\Anaconda3\envs\tensorflow_gpu\lib\site-packages\numpy\lib\type_check.py:546: DeprecationWarning: np.asscalar(a) is deprecated since NumPy v1.16, use a.item() instead
  'a.item() instead', DeprecationWarning, stacklevel=1)
.C:\Users\uv2ut\Anaconda3\envs\tensorflow_gpu\lib\site-packages\tensorflow\python\util\tf_inspect.py:55: DeprecationWarning: inspect.getargspec() is deprecated since Python 3.0, use inspect.signature() or inspect.getfullargspec()
  if d.decorator_argspec is not None), _inspect.getargspec(target))
.........
----------------------------------------------------------------------
Ran 16 tests in 0.092s

OK

早速使ってみる

サンプルノートブックファイルは以下にあります。

(任意のフォルダー)\research\object_detection\object_detection_tutorial.ipynb

新たな写真を追加して判定させたい場合

上記のサンプルノートブックファイルが参照する画像ファイルは以下のフォルダーにあります。 (任意のフォルダー)\research\object_detection\test_images

私の環境下では、以下のファイルにサンプルコードの画像ファイルがありました。

C:\Users\uv2ut\obj-detect\models-master\research\object_detection\test_images

f:id:nprogram:20190428173501p:plain

参考リンク

matplotlib基礎

はじめに

matplotlibでグラフを書きます。

図を描いてみる

import matplotlib.pyplot as plt
plt.style.use('seaborn-whitegrid')
import numpy as np
%matplotlib inline

# numpy.linspace(start, stop, num = 50, endpoint = True, retstep = False, dtype = None)
# num: 生成する配列(ndarray)の要素数を指定。
# endpoint: 生成する数列において、stopを要素に含むかどうかを指定。Trueなら含み、Falseなら含まない。
# retstep: 生成された配列(ndarray)の後に公差を表示するかどうかを指定。Trueなら表示し、Falseなら非表示。
# dtype: 出力された配列(ndarray)のデータ型を指定。指定がない場合、データ型はfloat。
x = np.linspace(0, 10, 1000)

print(x)
print(type(x))

# figureの縦横の大きさ
fig = plt.figure()

# figure内の枠の大きさとどこに配置している。subplot(行の数,列の数,何番目に配置しているか)
ax = plt.axes()

plt.plot(x, np.sin(x))
plt.plot(x, np.cos(x))
[ 0.          0.01001001  0.02002002  0.03003003  0.04004004  0.05005005
  0.06006006  0.07007007  0.08008008  0.09009009  0.1001001   0.11011011

・・・

  9.90990991  9.91991992  9.92992993  9.93993994  9.94994995  9.95995996
  9.96996997  9.97997998  9.98998999 10.        ]
<class 'numpy.ndarray'>

f:id:nprogram:20190424045507p:plain

複数の図を描いてみる

matplotlib.pyplot.subplotを使って規則正しくグラフを書きます。

2×2で4枚のグラフを描きます。

プロット番号は、左上が 1 で、右方向、下方向へいくにしたがい値が大きくなります。 たとえば、2 × 2 のグリッドの場合は

1 2

3 4

となります。

%matplotlib inline
import matplotlib.pyplot as plt
plt.style.use('seaborn-whitegrid')
import numpy as np

x = np.linspace(-3, 3, 20)
y1 = x
y2 = x ** 2
y3 = x ** 3
y4 = x ** 4

fig = plt.figure()

# 左上
plt.subplot(2,2,1)
plt.plot(x,y1)

# 右上
plt.subplot(2,2,2)
plt.plot(x, y2)

# 左下
plt.subplot(2,2,3)
plt.plot(x,y3)

# 右下
plt.subplot(2,2,4)
plt.plot(x,y4)

f:id:nprogram:20190424055536p:plain

matplotlib.pyplot.subplot

グリッド上に規則正しくグラフを配置する場合はsubplotメソッドを使います。

フォーマット

subplot(行数, 列数, プロット番号)

行数 × 列数 のグリッドに figure が分割され、プロット番号の位置に座標軸が作成されます。

np.linspace

NumPyのnp.linspaceは、線形に等間隔な数列を生成する関数です。

同様の数列をnp.arangeで生成することもできますが、np.linspaceを使用したほうがコード量を減らすことができます。

numpy.linspace(start, stop, num = 50, endpoint = True, retstep = False, dtype = None)

params:

パラメータ名 概要
start intまたはfloat 数列の始点を指定します。
stop intまたはfloat 数列の終点を指定します。
num int (省略可能)初期値50
生成する配列(ndarray)の要素数を指定します。
endpoint bool値 (省略可能)初期値True
生成する数列において、stopを要素に含むかどうか指定します。Trueなら含み、Falseなら含みません。
retstep boo値 (省略可能)初期値False
生成された配列(ndarray)の後に公差を表示するかどうか指定します。Trueなら表示し、Falseなら非表示です。
dtype dtype (省略可能)初期値None
出力された配列(ndarray)のデータ型を指定します。dtypeが指定されない場合、データ型は基本的にはfloatになっている。

returns:

num等分された等差数列を要素とするndarrayが返されます。

リンク

C++で関数型プログラミング (filter関数の実装)

はじめに

C++で、関数型プログラミングでいうfilter関数(抽出の処理を行う関数のこと)を使う場合は、以下のテンプレート関数を使うといいです。

  • copy_if
  • remove_copy_if

コード例

以下のコード例では、ラムダ式と挿入イテレータが使用されています。

挿入イテレータ(insert iterator)は、イテレータに対する代入処理を挿入処理に置き換える特殊な出力イテレータです。

#include <iostream>
#include <vector>
#include <numeric>
#include <algorithm>
using namespace std;


void getCharVector(std::vector<char> &someVector, const std::string someString)
{
    // 1文字つずつ取り出してvector<char>に格納する
    for (auto var : someString)
    {
        someVector.push_back(var);
    }
}


int main(void)
{
    std::vector<char> temp;

    getCharVector(temp, "a1a2a3a4a5a6a7a8a9a10");

    std::vector<char> filtered;

    // copy_ifテンプレート関数は、条件を満たした要素のみをコピーする機能
    std::copy_if(temp.begin(), temp.end(), std::back_inserter(filtered), [](char c) { return c == 'a'; });

    std::for_each(filtered.begin(), filtered.end(), [](char c) {std::cout << c << std::endl; });

    // std::count_if とは、第3引数で与えられる単項関数(Unary function)の条件を満たす要素が配列やコンテナにいくつ含まれているか返すテンプレート関数
    int sum = std::count_if(temp.begin(), temp.end(), [](char c) { return c == 'a'; });

    std::cout << "total : " << sum << std::endl;
}
a
a
a
a
a
a
a
a
a
a
total : 10

template関数でfilter関数の実装

template関数を使えば、数列で文字列でも、同じfilter関数で処理できます。

#include <iostream>
#include <algorithm>
#include <vector>
#include <cassert>

template<class Container, class Predicate>
Container filter(const Container& c, Predicate f) {
    Container r;
    std::copy_if(begin(c), end(c), std::back_inserter(r), f);
    return r;
}

int main(void)
{
    // 配列をfileter template関数に渡す
    auto target = filter(std::vector<int>{2, 3, 4}, [](int i) { return i < 4; });
    
    for (auto var : target)
    {
        std::cout << var << std::endl;
    }
    
    // std::vector::back関数は末尾要素への参照を取得する関数
    assert(3 == target.back());
    
    // 文字列をfileter template関数に渡す
    auto targetString = filter(std::string("a::b_c()"), isalpha);
    
    // 変数の方を調べます(std::string型で返ってきます)    
    std::cout << typeid(targetString).name() << std::endl;
    
    for (auto var : targetString)
    {
        std::cout << var << std::endl;
    }
    
    assert("abc" == targetString);
}
2
3
NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
a
b
c

リンク