2016年10月2日日曜日

Raspberry Pi PIXEL

Raspberry Pi NOOBS 英語版のデスクトップ環境では、ブラウザが日本語を表示してくれないので、デスクトップ環境を日本語で入れ直そうと思い、再インストールを実行しました。
すると、見慣れぬ PIXEL の文字が。
インストーラーは3月頃のものですが、中身は最新版をダウンロードしてくるようです。
PIXEL というのは公式ブログによると PImproved Xwindows Environment, Lightweight” のことだそうです。

変わったところは。
起動中のメッセージが表示されなくなった。
デスクトップの背景画像とアイコンデザインが変わったので、見た目が変わりました。
Java 系のプログラミング環境は前からありましたか? いりません。
VNC のクライアントが入ってます。
ブラウザが Chrome 系になりました。でもデフォの検索エンジンは DuckDuckGo です。
コントロールパネル(とは言わない?)のアプリのインストール・アンインストールが便利なんだか、不便なんだか、わかりません。全部一覧で表示しようとするので、時間がかかります。

他にも変わったのでしょうけれど、盛りだくさんですね。
16G が標準です。

2016年6月18日土曜日

NOOBS_v1_9_2 2016-05-27-raspbian-jessie


  • NOOBS_v1_9_2
    • 1.07GB
    • Used 3.3G (Avail 2.5G [8GB])
    • GUI で起動
  • NOOBS LITE 2016-05-27-raspbian-jessie
    • 1.39GB
    • Used 3.3G (Avail 3.5G [8GB])
    • GUI で起動
  • NOOBS LITE 2016-05-27-raspbian-jessie-lite
    • 306.5MB
    • Used 839M (Avail 6.1G [8GB])
    • CUI で起動
NOOBS_v_1_9_2 は起動するとデスクトップ画面になります。office 系のソフトも入っているので、3.3G も使っています。これでは 4G のメモリでは入らないです。8G でも 2.5G しか空いていません。
デスクトップ画面で色々やりたい人向けです。

jessie の 1.39GB は NOOBS_v_1_9_2 よりも大きい。あとでインストールしてみます。

jessie lite は 306.5MB。先にこっちをインストール。
2016-05-27-raspbian-jessie-lite.zip を解凍すると2016-05-27-raspbian-jessie-lite.img が出来上がります。1.39GB です。

8GB SD メモリを挿入。SDFormatter でフォーマットして、わかりやすいように JESSIE と名前をつけておきます。

$ diskutil list
/dev/disk0 (internal, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        *160.0 GB   disk0
   1:                        EFI EFI                     209.7 MB   disk0s1
   2:                  Apple_HFS MacHD                   159.2 GB   disk0s2
   3:                 Apple_Boot Recovery HD             650.0 MB   disk0s3
/dev/disk1 (internal, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:     FDisk_partition_scheme                        *8.0 GB     disk1
   1:                 DOS_FAT_32 JESSIE                  8.0 GB     disk1s1
$

/dev/disk1 が JESSIE の SD メモリ。
書き込み。
$ diskutil unmountDisk /dev/disk1
Unmount of all volumes on disk1 was successful
$ sudo dd bs=1m if=~/Downloads/2016-05-27-raspbian-jessie-lite.img of=/dev/disk1

Password:
$ diskutil eject /dev/disk1
Disk /dev/disk1 ejected

4752.525158 secs (291901 bytes/sec)

起動すると cui。pi の raspberry でログイン。
Used 839M, Avail 6.1G

何もしなくても、ssh で他のパソコンからログイン可能。
これでも繋がる。
$ ssh pi@raspberrypi.local

設定は、
$ sudo raspi-config


次に、2016-05-27-raspbian-jessie.zip を解凍。
2016-05-27-raspbian-jessie.img が出来上がる。4GB。
同じように書き込む。
時間がかかる・・・
ので、諦める。
dd コマンドが途中で止められない・・・

その後、メモリを変えて、かつ、MacBook Pro の SD スロットではなく、USB アダプタでつないでみました。
4019191808 bytes transferred in 579.308803 secs (6937909 bytes/sec)
と、4GB で10分かかっていない。
その時のコマンド。bs=16m にしました。
$ sudo dd bs=16m if=~/Downloads/2016-05-27-raspbian-jessie.img of=/dev/disk4



ついでに、こちらも2回目の挑戦。
$ diskutil unmountDisk /dev/disk4
$ sudo dd bs=16m if=~/Downloads/2016-05-27-raspbian-jessie-lite.img of=/dev/disk4
$ diskutil eject /dev/disk4


で、結果は。
1387266048 bytes transferred in 205.836497 secs (6739650 bytes/sec)

4分弱でした。
SD スロットが不調なのかもしれません。

bs=1m と 16m の違いか?
これで確認。SD メモリは東芝製の class 10 made in Japan です。
$ diskutil unmountDisk /dev/disk4
$ sudo dd bs=1m if=~/Downloads/2016-05-27-raspbian-jessie-lite.img of=/dev/disk4

Password:
1323+0 records in
1323+0 records out
1387266048 bytes transferred in 174.826092 secs (7935120 bytes/sec)
$ diskutil eject /dev/disk4

こちらの方が速かった。



おまけ:
SD メモリを取り替えて、ssh でつなごうとすると怒られます。
そんな時は、「$ vi .ssh/known_hosts」で「raspberrypi.local」の行を削除しましょう。

Raspberry Pi の ~/.ssh/authorized_keys に、つなぎに行くほうの .ssh/id_rsa.pub の内容を貼り付けておくとパスワードなしでログインできるようになります。

2016-09-23-raspbian-jessie.zip は MacOS X El Capitan 標準のアーカイバでは解凍出来ないので The Unarchiver を使いました。

2016年2月20日土曜日

Raspberry Pi 2 Model B + NOOBS Lite 1.7

Raspberry Pi 2 Model B に NOOBS Lite 1.7 をインストールしてみた。

ここを見ながら、SD メモリをフォーマットして、NOOBS Lite 1.7 を解凍してできたファイルをドラッグアンドドロップして起動する。

OS の選択と、言語とキーボードの選択をする。HHK US 配列を使っているので、US の英語にしておく。

インストールが終わって再起動すると GUI の画面が立ち上がるようになっている。
ユーザーのパスワード設定の画面がなくなった?
デフォで pi の raspberry になっている。

画面の縁が黒いので、再起動する時にシフトキーを押したままにして設定画面を表示して、縁を出ないようにする。
Edit Config をクリックして、一番下の disable_overscna の設定を =0 ではなく =1 にする。
ここは次の raspi-config でも設定できる。

いろいろ設定をする raspi-config がどこかに行ってしまったので、
$ sudo raspi-config する。
GUI からでも設定できるメニューが追加されていた。便利。
wifi も簡単につながるし、便利になった。



デフォで、ssh が使えるので、パスワードの変更と TimeZone、GUI で起動する必要はないので text で起動するように設定する。ここはお好みで。
TimeZone は Asia/Tokyo にする。

GUI で起動した時と text の時のメモリ使用状況の違い。
ひとつめが GUI、ふたつめが text 。
used の 190168 と 74512 を比べると、半分以下になっている。
pi@raspberrypi:~ $ free
             total       used       free     shared    buffers     cached
Mem:        948140     190168     757972       6924      15008      98852
-/+ buffers/cache:      76308     871832

Swap:       102396          0     102396

pi@raspberrypi:~ $ free
             total       used       free     shared    buffers     cached
Mem:        948140      74512     873628       6384       7256      36428
-/+ buffers/cache:      30828     917312
Swap:       102396          0     102396
pi@raspberrypi:~ $ 

2014年2月21日金曜日

Raspberry Pi + OpenCV 日経Linux の顔認識が動かない

日経Linux の 2013/8 や「電子工作入門」に掲載されている「専用カメラモジュールを活用“美女Linux”を顔認識」をやってみた。
その結果は、動かなかった。
まず、この記事で使用している「まなみん」だか「てるみん」という女性の顔写真が入手できない。しかたがないので、IMDb で適当な番組を検索して、その出演者の顔写真をダウンロードして使用した。
3/4 くらいは認識できなかった。
Wil Wheaton、Patrick Stewart、Naveen Andrews、Michael Emerson、Matthew Fox、LeVar Burton、Ken Leung、Josh Holloway、Jorge Garcia、Jonathan Frakes、Grace Park、Brent Spiner、Mayim Bialik、Simon Helberg、Johnny Galecki、Kunal Nayyar は認識できる顔写真だった。さらに探して20枚でやってみた。
で、実行すると・・・。
pi@raspberrypi /opt/vc/camcv $ ./camcv face.cfg 1 5000
start
(init) People initialized
(OK) csv=face.cfg
(init) 10 pictures read to train
(init) 10 pictures of Pierre (0) read to train
(init) 0 pictures of Natacha (1) read to train
(init) 0 pictures of Mona Lisa (2) read to train
(init) 0 pictures of Lisa (3) read to train
(OK) read CSV ok
(init) taille images ok
(init) start train images
(init) train images : ok
(init) Load modele : ok
Xlib:  extension "RANDR" missing on display ":1.0".
mmal: main: Failed to create preview component
mmal: Failed to run camera app. Please check for firmware updates

2668812741 seconds for 0 frames : FPS = 0.000000
pi@raspberrypi /opt/vc/camcv $ 

「mmal: main: Failed to create preview component」と言われてしまう。
このメッセージの出所を調べると、camcv_vid1.cpp の 764 行めあたりにあるこれ「else if (!raspipreview_create(&state.preview_parameters))」が、エラーの条件を判断しているところであることがわかった。
次に、「raspipreview_create()」が何を返しているかを調べてみた。
RaspiPreview.h で宣言されていて、MMAL_STATUS_T を返している。
それは、mmal_types.h に定義されている enum の値であった。
見ると、「MMAL_SUCCESS = 0」となっているではないか。
さきほどの「else if (!raspipreview_create()」は0でなければエラーとしている。
でも0なら MMAL_SUCCESS ということで、エラーの無い状態です。
逆なんです。というわけで 764 行めを次のように変更した。
else if (raspipreview_create(&state.preview_parameters) != MMAL_SUCCESS)
0でエラー、ではなく、0でなければエラー、にした。
これで一応なんとか動いているが、しばらくするとやっぱりエラーがでる。
pi@raspberrypi / $ /opt/vc/camcv/camcv /opt/vc/camcv/face.cfg 1 5000
start
(init) People initialized
(OK) csv=/opt/vc/camcv/face.cfg
(init) 10 pictures read to train
(init) 10 pictures of Pierre (0) read to train
(init) 0 pictures of Natacha (1) read to train
(init) 0 pictures of Mona Lisa (2) read to train
(init) 0 pictures of Lisa (3) read to train
(OK) read CSV ok
(init) taille images ok
(init) start train images
(init) train images : ok
(init) Load modele : ok
Xlib:  extension "RANDR" missing on display ":1.0".
mmal: Failed to run camera app. Please check for firmware updates

65 seconds for 208 frames : FPS = 3.200000
pi@raspberrypi / $ 

これって、そうしているようです。
同じソースファイル camcv_vid1.cpp の 233 行めにこれがありました。
state->timeout = 65000; // capture time : here 65 s
65秒で止まるようにしてありました。でも「Please check for firmware updates」は無いと思います。

2014年1月24日金曜日

SDメモリの丸ごとバックアップ

SDメモリを丸ごとバックアップする方法について書いておく。
こうして作成したバックアップファイルをリストアする方法についても書いておく。

まず、バックアップ。(disk3の場合。これの確認は $ df -h)
$ sudo diskutil unmount /dev/disk3s1
$ sudo diskutil unmount /dev/disk3s5
$ sudo dd if=/dev/disk3 of=~/Desktop/RaspberryPi_20130620.img bs=8m
$ sudo diskutil eject /dev/rdisk3

あるいは?
$ sudo diskutil unmount /dev/disk3s1
$ sudo diskutil unmount /dev/disk3s5
$ sudo dd if=/dev/rdisk3 of=~/Desktop/RaspberryPi_20130620.img bs=8m
$ sudo diskutil eject /dev/rdisk3

次にリストアする。(disk4の場合)
$ sudo diskutil unmount /dev/disk4s1
$ sudo dd bs=8m if=~/Desktop/RaspberryPi_20130620.img of=/dev/rdisk4
$ sudo diskutil eject /dev/rdisk4

bs=8m にしているけれど、てきとうです。

2014年1月8日水曜日

OpenCV で、C のソースを Python にする

OpenCV の C のソースを Python に変換するときのメモ。
C にしておくと、ソースとオブジェクトの二つのファイルの管理が必要となったり、ライブラリの置く場所など、いろいろめんどう。
というわけで、Python にしてしまおうという計画。

言語文法上で注意するのはこれくらい?
  1. C の文は「;」で終了するが、Python にはない。
  2. C の変数宣言では型が必要だが、Python は変数名だけ。
  3. C では「&」をつけて、その変数のポインタを求めたりするが、Python では不要。
  4. True/False や Not の表記
  5. nil や NULL や None の表記
  6. Python のインデント。
「import cv」とすると、メソッド名などに「cv.」をつけることになる。
しかし、cv. の後のメソッド名には「cv」がつかない。
ただし、定数名の頭についている「CV」はそのまま残る。
こんな感じ。

C:
frame = cvQueryFrame(capture);
cvSmooth(frame, frame, CV_GAUSSIAN, 3, 3);

Python:
frame = cv.QueryFrame(capture)
cv.Smooth(frame, frame, cv.CV_GAUSSIAN, 3, 3)

C の cvQueryFrame は Python では cv.QueryFrame となる。
ただし定数は、C で CV_GAUSSIAN、Python で cv.CV_GAUSSIAN となる。

厄介なのがマクロ(?)。Python にはない。ふつーにタプルで表現したりする。

C:
const int w = frame->width;
const int h = frame->height;
imgR = cvCreateImage(cvSize(w, h), IPL_DEPTH_8U, 1);
cvCircle(frame, cvPoint(gX, gY), 80, CV_RGB(0,0,255), 6, 8, 0);

Python:
the_size = cv.GetSize(frame)
imgR = cv.CreateImage(the_size, cv.IPL_DEPTH_8U, 1)
cv.Circle(frame, (gX, gY), 80, (0, 0, 255), 6, 8, 0)

そのほか、調べないとわからないもの。

C:
cvMoments(imgResult, &moments, 0);
double m00 = cvGetSpatialMoment(&moments, 0, 0);

Python:
moments = cv.Moments(cv.GetMat(imgResult, 1), 0)
m00 = cv.GetSpatialMoment(moments, 0, 0)


サンプルとして、次のページにあった赤い色のエリアを抽出し、重心を求めるソースの C 版と Python 版を示す。
http://d.hatena.ne.jp/shokai/20090203/1233609981
http://opencv-srf.blogspot.ro/2010/09/object-detection-using-color-seperation.html

これは Mac (10.9.1 Mavericks) と Raspberry Pi で動作確認した。

C:
#include <opencv/cv.h>
#include <opencv/highgui.h>

// This function threshold the HSV image and create a binary image
IplImage* GetThresholdedImage(IplImage* imgHSV) {
    IplImage* imgResult = cvCreateImage(cvGetSize(imgHSV), IPL_DEPTH_8U, 1);
    cvInRangeS(imgHSV, cvScalar(150, 160, 60), cvScalar(200, 256, 256), imgResult);
    return imgResult;
}

int main() {
    CvCapture* capture = NULL;
    IplImage *frame = NULL;
    IplImage *imgR = NULL, *imgG = NULL, *imgB = NULL;
    IplImage *imgThreshold_R = NULL, *imgThreshold_G = NULL, *imgThreshold_B = NULL;
    IplImage *imgTmp = NULL;
    IplImage *imgHSV = NULL;
    IplImage *imgResult = NULL;
    CvMoments moments;
    
    capture = cvCaptureFromCAM(0);
    if (!capture) {
        printf("Capture failure\n");
        return -1;
    }
    
    cvNamedWindow("Video");
    cvNamedWindow("Results");
    
    
    // iterate through each frames of the video
    while (true) {
        
        frame = cvQueryFrame(capture);
        if (!frame) {
            break;
        }
        
        frame = cvCloneImage(frame);
        cvSmooth(frame, frame, CV_GAUSSIAN, 3, 3); // smooth the original image using Gaussian kernel
                
        if (1) {
            const int w = frame->width;
            const int h = frame->height;
            
            imgR = cvCreateImage(cvSize(w, h), IPL_DEPTH_8U, 1);
            imgG = cvCreateImage(cvSize(w, h), IPL_DEPTH_8U, 1);
            imgB = cvCreateImage(cvSize(w, h), IPL_DEPTH_8U, 1);
            imgThreshold_R = cvCreateImage(cvSize(w, h), IPL_DEPTH_8U, 1);
            imgThreshold_G = cvCreateImage(cvSize(w, h), IPL_DEPTH_8U, 1);
            imgThreshold_B = cvCreateImage(cvSize(w, h), IPL_DEPTH_8U, 1);
            imgResult = cvCreateImage(cvSize(w, h), IPL_DEPTH_8U, 1);
            imgTmp = cvCreateImage(cvSize(w, h), IPL_DEPTH_8U, 1);

            cvSplit(frame, imgB, imgG, imgR, NULL); // BGRを分解
            
            // 赤の要素が100以上で、緑と青より1.5倍以上あるピクセルを抽出
            cvThreshold(imgR, imgThreshold_R, 100, 255, CV_THRESH_BINARY);
            cvDiv(imgR, imgG, imgTmp, 10); // 10倍
            cvThreshold(imgTmp, imgThreshold_G, 15, 255, CV_THRESH_BINARY);
            cvDiv(imgR, imgB, imgTmp, 10);
            cvThreshold(imgTmp, imgThreshold_B, 15, 255, CV_THRESH_BINARY);
            cvAnd(imgThreshold_G, imgThreshold_B, imgTmp, NULL);
            cvAnd(imgTmp, imgThreshold_R, imgResult, NULL);
            
            cvMoments(imgResult, &moments, 0);
            double m00 = cvGetSpatialMoment(&moments, 0, 0);
            double m10 = cvGetSpatialMoment(&moments, 1, 0);
            double m01 = cvGetSpatialMoment(&moments, 0, 1);
            int gX = m10 / m00;
            int gY = m01 / m00;
            cvCircle(frame, cvPoint(gX, gY), 80, CV_RGB(0,0,255), 6, 8, 0);
        } else {
            imgHSV = cvCreateImage(cvGetSize(frame), IPL_DEPTH_8U, 3);
            cvCvtColor(frame, imgHSV, CV_BGR2HSV); // Change the color format from BGR to HSV
            imgResult = GetThresholdedImage(imgHSV);
            cvSmooth(imgResult, imgResult, CV_GAUSSIAN, 3, 3); // smooth the binary image using Gaussian kernel
        }
        cvShowImage("Results", imgResult);
        cvShowImage("Video", frame);
        
        
        // Clean up used images
        cvReleaseImage(&imgHSV);
        cvReleaseImage(&imgResult);
        cvReleaseImage(&frame);
        
        // Wait 50mS
        int c = cvWaitKey(10);
        // If 'ESC' is pressed, break the loop
        if ((char)c == 0x1b ) {
            break;
        }
    }
    
    cvDestroyAllWindows() ;
    cvReleaseCapture(&capture);
    
    return 0;
}

Python:
#!/usr/bin/env python
# coding: UTF-8
"""
DetectingRedObjects.py

"""
import cv

def GetThresholdedImage(imgHSV):
    imgResult = cv.CreateImage(cv.GetSize(imgHSV), cv.IPL_DEPTH_8U, 1)
    cv.InRangeS(imgHSV, cv.Scalar(150, 160, 60), cv.Scalar(200, 256, 256), imgResult)
    return imgResult

def main():
    capture = None
    frame = None
    imgR = imgG = imgB = None
    imgThreshold_R = imgThreshold_G = imgThreshold_B = None
    imgTmp = imgHSV = imgResult = None
    moments = None
    
    capture = cv.CaptureFromCAM(0)
    if (not capture):
        print("Capture failure")
        return -1
    
    cv.NamedWindow("Video")
    cv.NamedWindow("Results")
    
    
    # iterate through each frames of the video
    while (True):
        frame = cv.QueryFrame(capture)
        if (not frame):
            break;
        
        frame = cv.CloneImage(frame)
        cv.Smooth(frame, frame, cv.CV_GAUSSIAN, 3, 3) # smooth the original image using Gaussian kernel
        
        if (True):
            # 赤色領域を検出(3) 重心も計算
            # http://d.hatena.ne.jp/shokai/20090203/1233609981
            the_size = cv.GetSize(frame)
            # w = frame.width
            # h = frame.height
            
            imgR = cv.CreateImage(the_size, cv.IPL_DEPTH_8U, 1)
            imgG = cv.CreateImage(the_size, cv.IPL_DEPTH_8U, 1)
            imgB = cv.CreateImage(the_size, cv.IPL_DEPTH_8U, 1)
            imgThreshold_R = cv.CreateImage(the_size, cv.IPL_DEPTH_8U, 1)
            imgThreshold_G = cv.CreateImage(the_size, cv.IPL_DEPTH_8U, 1)
            imgThreshold_B = cv.CreateImage(the_size, cv.IPL_DEPTH_8U, 1)
            imgResult = cv.CreateImage(the_size, cv.IPL_DEPTH_8U, 1)
            imgTmp = cv.CreateImage(the_size, cv.IPL_DEPTH_8U, 1)
            
            cv.Split(frame, imgB, imgG, imgR, None) # BGRを分解
            
            # 赤の要素が100以上で、緑と青より1.5倍以上あるピクセルを抽出
            cv.Threshold(imgR, imgThreshold_R, 100, 255, cv.CV_THRESH_BINARY)
            cv.Div(imgR, imgG, imgTmp, 10) # 10倍
            cv.Threshold(imgTmp, imgThreshold_G, 15, 255, cv.CV_THRESH_BINARY)
            cv.Div(imgR, imgB, imgTmp, 10)
            cv.Threshold(imgTmp, imgThreshold_B, 15, 255, cv.CV_THRESH_BINARY)
            cv.And(imgThreshold_G, imgThreshold_B, imgTmp, None)
            cv.And(imgTmp, imgThreshold_R, imgResult, None)
            
            # cv.Moments(imgResult, moments, 0)
            moments = cv.Moments(cv.GetMat(imgResult, 1), 0)
            m00 = cv.GetSpatialMoment(moments, 0, 0)
            m10 = cv.GetSpatialMoment(moments, 1, 0)
            m01 = cv.GetSpatialMoment(moments, 0, 1)
            if (m00 != 0):
                gX = int(m10 // m00)
                gY = int(m01 // m00)
                # cvCircle(frame, cvPoint(gX, gY), 80, CV_RGB(0,0,255), 6, 8, 0);
                cv.Circle(frame, (gX, gY), 80, (0, 0, 255), 6, 8, 0)
        else:
            # Color Detection & Object Tracking
            # http://opencv-srf.blogspot.ro/2010/09/object-detection-using-color-seperation.html
            imgHSV = cv.CreateImage(cv.GetSize(frame), cv.IPL_DEPTH_8U, 3)
            cv.CvtColor(frame, imgHSV, cv.CV_BGR2HSV) # Change the color format from BGR to HSV
            imgResult = GetThresholdedImage(imgHSV)
            cv.Smooth(imgResult, imgResult, cv.CV_GAUSSIAN, 3, 3) # smooth the binary image using Gaussian kernel

        cv.ShowImage("Results", imgResult)
        cv.ShowImage("Video", frame)
        
        
        # Clean up used images
        # cv.ReleaseImage(imgHSV)
        # cv.ReleaseImage(imgResult)
        # cv.ReleaseImage(frame)
        
        # Wait 50mS
        c = cv.WaitKey(10)
        # If 'ESC' is pressed, break the loop
        if (c == 0x1b):
            break

    cv.DestroyAllWindows()
    # cv.ReleaseCapture(capture)
    return 0


if __name__ == '__main__':
    main()

2013年12月13日金曜日

Raspberry Pi (その前に Mac で)+ OpenCV + OpenNI + Xtion Pro Live

まず、Mac でいろいろやってみる。
OpenCV は MacPorts で opencv @2.4.7_1+openni+python27 をインストールする。
OpenNI も MacPorts で一応入れたものの・・・openni @1.5.7.10_0
OpenNI-MacOSX-x64-2.2 をダウンロード。
「OpenNI-MacOSX-x64-2.2/Samples/Bin」にあるサンプルは動作している。

次に、Samples のソースをいじる前に、make できることを確認する。
make すると deprecated のエラーがでてしまう。
Makefile を修正してコンパイルオプションに「-Wno-deprecated」を追加する。
例を示す。
<<修正前>>
CFLAGS += -Wall -D_CLOSEST_POINT
<<修正後>>
CFLAGS += -Wall -D_CLOSEST_POINT -Wno-deprecated



ClosestPointViewer を make するには、MWClosestPoint を先に make しておかなければならない。
MWClosetPointApp を make するときも、先に MWClosestPoint を make しておかなければならない。

まず、MWClosestPoint/Bin は削除してから、MWClosestPoint を make する。

次に、ClosestPointViewer/Bin/ にある Intermediate と x64-Release の二つのディレクトリは空にする。
MWClosestPoint/Bin/x64-Release/libMWClosestPoint.dylib を、先ほど空にした ClosestPointViewer/Bin/x64-Release/ にコピーする。
コピーコマンドはこれ。
$ cp MWClosestPoint/Bin/x64-Release/libMWClosestPoint.dylib ClosestPointViewer/Bin/x64-Release/
そして、ClosestPointViewer を make する。

同様に、MWClosestPointApp/Bin/ にある Intermediate と x64-Release の二つのディレクトリは空にする。
MWClosestPoint/Bin/x64-Release/libMWClosestPoint.dylib を、先ほど空にした MWClosestPointApp/Bin/x64-Release/ にコピーする。
コピーコマンドはこれ。
$ cp MWClosestPoint/Bin/x64-Release/libMWClosestPoint.dylib MWClosestPointApp/Bin/x64-Release/
MWClosetPointApp を make する。

make できることが確認できたので、ソースをいろいろいじってみることにする。