Raspberry PiでGPIO制御を行う
今回はいつも調べてしまう、ラズパイでのGPIO制御についてまとめておこうと思います!!
毎度調べるのも手間なので。。。
■環境
今回はraspberry Pi 4を用いて動作確認し、そちらの紹介を行っていきます。
【国内正規代理店品】Raspberry Pi4 ModelB 4GB ラズベリーパイ4 技適対応品【RS・OKdo版】 新品価格 |
ただ、raspberry Pi 3でも動作する手順になっています。
■ピン配置の確認
まずはraspberry Piのピン配置について記載していきます。
公式(https://www.raspberrypi.org/documentation/usage/gpio/README.md)より、ピン配置はこちら。
コマンドによりピン配置の確認ができます。
こちらのコマンドを実行すると、
pinout
こちらのようにピン配置の結果が得られます。
■コマンドでのGPIO制御
では早速GPIO制御についてまとめていきたいと思います!!
今回使用するGPIOですが、
out:gpio17
in:gpio27
で設定していきたいと思います!!
gpio**の部分を自分が使用したいgpioの番号をセットすればOKです。
GPIOを制御するにあたって、
/sys/class/gpio
配下に格納されたファイルを操作していきます。
まずは使用するGPIOを定義していきます。
こちらのようにコマンドを実行すればOKです。
echo 27 > /sys/class/gpio/export echo 17 > /sys/class/gpio/export
すると、/sys/class/gpio配下に
gpio27、gpio17
が追加されているかと思います。
次に、gpio17、gpio27をin outに変更していきたいと思います。
gpio27をinにするには、
echo in > /sys/class/gpio/gpio27/direction
とすればよく、
gpio17をoutにするためには、
echo out > /sys/class/gpio/gpio17/direction
とすればOKです。
■動作確認
では、正しく設定されているか確認してみます。
GPIOのon(1)/off(0)は、
/sys/class/gpio/gpio17/value /sys/class/gpio/gpio27/value
まずはinから!!
あらかじめGPIO17へボタンを接続しておきます。
ボタン押下せずに
cat /sys/class/gpio/gpio27/value
を実行すると、
0
が表示されるかと思います。
ボタンを押下しながら、
cat /sys/class/gpio/gpio27/value
を実行すると、
1
が表示され、gpioのinが有効になっていることが確認できます。
次にout!!
あらかじめLEDを接続しておきます。
echo 1 > /sys/class/gpio/gpio17/value
とするとLEDが点灯し、
echo 0 > /sys/class/gpio/gpio17/value
とするとLEDが消灯することが確認できるかと思います。
Reactで雪を降らせてみる
メリークリスマス!!
ただ残念なことに、
コロナウィルスの第3波が来てしまって、遊びに行くことも憚られる状態ですね😢
せっかくのクリスマスなのに、、、
例年ならイルミネーションとかきれいなはずなのに😨
ということで、クリスマスっぽいWebアプリを作ってみることにしました!!
作成はReactを用いました!!
■Reactで雪を降らせる
Reactで雪を降らせるにあたり、snow-fallというAPIを用いました。
https://www.npmjs.com/package/react-snowfall
まずはsnow-fallのセットアップです。
こちらのコマンドを実行!!
sudo npm i react-snowfall yarn add react-snowfall
では、実際に雪を降らせるコードを作成します。
サンプルコードを利用して、このように作成しました。
import React, { Component } from 'react'; import Snowfall from 'react-snowfall'; export default class Snow extends Component { render() { const {position} = this.state; const {City} = this.state; var Pos = position; return ( <div> <div className="layout" style={{ height: 850, width: 1850, background: '#282c34' }}> <Snowfall /> </div>, </div> ); } }
snow-fallライブラリを用いれば実装は簡単で、
<Snowfall />
をコールすれば雪を降らせることが可能です!!
今回は背景を黒色にして雪を目立つようにしています。
<div className="layout" style={{ height: 850, width: 1850, background: '#282c34' }}>
こちらを動作させるとこんな感じになります。
雪を降らすことが出来ました!!
後、Configurationをセットすれば雪の量や色を変更することが可能になります。
ただ、雪の結晶サイズはどうやら変更できない模様です。。
■メリークリスマスw
雪を降らせることが出来たので、ちょっとクリスマスっぽいアプリを作成してみました!!
作成したアプリを実行するとこんな感じになります。
クリスマスっぽいですかね??
コードはこんな感じになります。
import React, { Component } from 'react'; import Snowfall from 'react-snowfall'; import Tokyo from './image/Area1.JPG'; import Yokohama from './image/Area2.JPG'; import Tower from './image/Area3.JPG'; import Santa from './image/santa.png'; import Tide from './image/Tide.png'; import "./snow.css" export default class Snow extends Component { constructor (props) { super(props); this.state = { position:1600, City:Tokyo, Count:0, }; } SantaMove=()=>{ var {position} = this.state; var Pos = position; const {Count} = this.state; if(Pos <= 10){ this.setState({position:1600}); switch(Count){ case 0: this.setState({City:Yokohama}); this.setState({Count:1}); break; case 1: this.setState({City:Tower}); this.setState({Count:2}); break; case 2: this.setState({City:Tokyo}); this.setState({Count:0}); break; default: this.setState({City:Tokyo}); this.setState({Count:0}); break; } }else{ this.setState({position:Pos-20}); } } componentDidMount() { this.intervalId = setInterval(()=>{ this.SantaMove(); }, 200); } render() { const {position} = this.state; const {City} = this.state; var Pos = position; return ( <div> <div className="layout" style={{ height: 850, width: 1850, background: '#282c34' }}> <img src={Santa} alt="Santa" id="santaID" className="santa" style={{left:Pos}}/> <img src={City} alt="City" height="850" width="1850" /> <img src={Tide} alt="Tide" className="Tide" /> <Snowfall snowflakeCount={300}/> </div>, </div> ); } }
サンタクロースの動作ですが、
componentDidMount() { this.intervalId = setInterval(()=>{ this.SantaMove(); }, 200); }
により、200ms毎にSantaMove()関数をコールしており、
SantaMove()関数は、
SantaMove=()=>{ var {position} = this.state; var Pos = position; const {Count} = this.state; if(Pos <= 10){ this.setState({position:1600}); switch(Count){ case 0: this.setState({City:Yokohama}); this.setState({Count:1}); break; case 1: this.setState({City:Tower}); this.setState({Count:2}); break; case 2: this.setState({City:Tokyo}); this.setState({Count:0}); break; default: this.setState({City:Tokyo}); this.setState({Count:0}); break; } }else{ this.setState({position:Pos-20}); } }
となります。
20px毎に動かして、10px以下の場合には別の背景に切り替えるような制御となっております。
■最後に
今回は雪を降らせてサンタクロースを動かしてみました!!
ライブラリが用意されていると簡単にアプリを作成させることが出来ますね!!
OpenCVをの用いた画像処理系まとめてみた
今年も後わずかですね!!
年を取るにつれて1年が短く感じます。
5月から始めたこの技術ブログも結構続いていることに自分でも驚いております!!
さて今回は、
今までまとめてきたコードの整理と今後簡単に使えるようにするためにAPI化してみましたので、
その報告です。
- ■整理したコード格納先
- ■まとめたAPI報告
- ■ARマーカーの作成や読み込み
- ■バーコードの作成と読み込み
- ■画像データのバイト列変換やバイト列から画像データへの変換
- ■ビデオストリーミング用API
- ■画像重畳やRGB分割用API
- ■顔や目などの体の一部検知用API
- ■ビデオストリーミング+体の一部検知用API
- ■最後に
■整理したコード格納先
こちらになります。
https://github.com/Elsammit/ImageAPI
■まとめたAPI報告
まずはどんな内容をAPIとして整理したか、です。
一覧にするとこんな感じ。
・ARMaker.py:ARマーカーの作成や読み込み
・BarcodeMaker.py:バーコードの作成と読み込み
・ConvertImgByte.py:画像データのバイト列変換やバイト列から画像データへの変換
・OnlyVideoStreaming.py:ビデオストリーミング
・Overlap.py:画像重畳やRGB分割用API
・PartDetection.py:顔や目などの体の一部検知用API
・VideoStreamAndDetection.py:ビデオストリーミング+体の一部検知用API
■ARマーカーの作成や読み込み
Classとして、
・MakeArMaker:ARマーカー作成
・ReadMaker:ARマーカー読み取り
を用意。
使用例はこんな感じです。
if __name__ == '__main__': MakeArMaker = MakeArMaker() MakeArMaker.ARGeneratorFile("aaa.jpg",0,150) MakeArMaker.MaltiARGenerator("bbb.jpg", 0, 6, 150) ReadMaker = ReadMaker() cap = cv2.VideoCapture(0) while True: ret, frame = cap.read() ReadMaker.ARReader(frame, None) cv2.imshow('drawDetectedMarkers', frame) #マーカが描画された画像を表示 cv2.waitKey(1) #キーボード入力の受付 cap.release() #ビデオキャプチャのメモリ解放 cv2.destroyAllWindows() #すべてのウィンドウを閉じる
■バーコードの作成と読み込み
Classとして、
・BarCodeMaker:バーコード作成と読み取り
を用意。
使用例はこんな感じです。
if __name__ == '__main__': BarCodeMaker = BarCodeMaker() Num = '9323131312131' BarCodeMaker.MakeBarCode("test.jpg", Num)
■画像データのバイト列変換やバイト列から画像データへの変換
Classとして、
・ImgByteChange:画像データとバイト列変換とバイト列から画像データ変換
を用意。
使用例はこんな感じ。
imgByteChange = ImgByteChange() bt = imgByteChange.ImageToByte("画像データ(例:test.jpg)") mt = imgByteChange.ByteToImage(bt)
■画像重畳やRGB分割用API
Classとして、
・Overlap:画像重畳
・ImageSeparateComposition:RGB分割、合成
・ImageHistgrams:ヒストグラム作成用
を用意。
ちょっと色々と詰め込みすぎ間が否めないな。。。
後で分けておこうかな??
■顔や目などの体の一部検知用API
Classとして、
・Detections:体の一部を検知するためのAPI
を用意。
目を検知するだけのコードですが、
使用例はこんな感じです。
img1 = cv2.imread('lena.jpg') m_Detections = Detections() eye_left, eye_right = m_Detections.EyeDetection("haarcascade_eye.xml", img1) img1 = m_Detections.DetectionOnRectangle("haarcascade_frontalface_default.xml", img1, 2, (255,0,0)) cv2.imshow("test", img1)
■ビデオストリーミング+体の一部検知用API
Classとして、
・VideoStreamClass:ビデオストリーミングを行ったり、体の一部を検知するためのAPI
を用意。
ストリーミングのみを行ったり、ストリーミング結果を録画したり、、、
体の一部を四角で囲んだりすることができるAPIです。
こちらも色々詰め込みすぎてる気がするけど、、、
基本的にストリーミング系を1つにまとめた感じになっているから、、、
まぁよしとするか!!
使用例はこんな感じになります。
if __name__ == '__main__': video = VideoStreamClass() #video.VideoStream(None) video.VideoWriterInit(30, 640, 480, "test.mp4") video.VideoStream(None)
カメラキャプチャ画像をバイト列で送受信
前回、Socket通信でやりたいことがあった!!と記載しました。
elsammit-beginnerblg.hatenablog.com
それが、
”カメラキャプチャ画像をバイト列に変換して送信しストリーミング配信を行ってみる”
ことです。
無駄なことだと思いますが、どうしてもやってみたくて調べてみました!!
問題なく動作させることが出来たので、方法をまとめておこうと思います。
■環境
今回こちらの構成で動作させてみました!!
前回と同様、ネットワークサーバをRaspberry Pi側に構築し、クライアントをwindows PCを用いました。
今回はpythonを用いるのですが、バージョンはこちらの通りです。
・windows PC側Pythonバージョン:3.7.4
・Raspberry Pi側Pythonバージョン:3.7.3
またカメラですが、UCAM-C520FBBKを使用しました。
エレコム WEBカメラ マイク内蔵 200万画素 高精細ガラスレンズ ブラック UCAM-C520FBBK 新品価格 |
■サーバ側構築
ではまずはサーバ側の構築です。
全体のコードはこちらです。
import socketserver import cv2 import numpy import socket import sys class TCPHandler(socketserver.BaseRequestHandler): def handle(self): self.data = self.request.recv(1024).strip() ret, frame=capture.read() jpegstring=cv2.imencode('.jpg', frame)[1].tostring() self.request.send(jpegstring) #hostとportを設定 HOST = 'host名' PORT = ポート番号 #カメラの設定 capture=cv2.VideoCapture(0) capture.set(3,320) capture.set(4,240) if not capture: print("Could not open camera") sys.exit() socketserver.TCPServer.allow_reuse_address = True server = socketserver.TCPServer((HOST, PORT), TCPHandler) server.capture=capture try: server.serve_forever() except KeyboardInterrupt: pass server.shutdown() sys.exit()
やっていることは、画像データをバイト列に変換し前回のsocket通信を実施しているのみです。
簡単には、
①データ受信により、TCPHandlerがコール
②画像データをバイト列に変換
jpegstring=cv2.imencode('.jpg', frame)[1].tostring()
③バイト列をレスポンス
self.request.send(jpegstring)
です。
■クライアント側構築
次にクライアント側の構築です。
コード全体はこちら。
import socket import numpy import cv2 def getimage(): #IPアドレスとポート番号は環境に応じて変更 HOST = '192.168.11.2' PORT = 8080 sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM) sock.connect((HOST,PORT)) sock.send(('a').encode("utf-8")) buf=b'' recvlen=100 while recvlen>0: receivedstr=sock.recv(1024) recvlen=len(receivedstr) buf +=receivedstr sock.close() narray=numpy.fromstring(buf,dtype='uint8') return cv2.imdecode(narray,1) while True: img = getimage() cv2.imshow('Capture',img) if cv2.waitKey(100) & 0xFF == ord('q'): break HOST = 'ホスト名' PORT = ポート番号 getimage()
こちらもsocket通信とバイト列から画像データ変換の組み合わせです。
具体的には、
sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM) sock.connect((HOST,PORT)) sock.send(('a').encode("utf-8"))
でバイト列を要求し、
recvlen=100 while recvlen>0: receivedstr=sock.recv(1024) recvlen=len(receivedstr) buf +=receivedstr
にてバイト列を全て受信。
受信したバイト列を画像データに変換。
narray=numpy.fromstring(buf,dtype='uint8') return cv2.imdecode(narray,1)
以上です。
■動作確認
こちらを動作させてみましたが、、、
う~~ん。。。
遅延が目立ちますね。。。
コードは320×240だったのですが、画像サイズを数倍拡大させると
より遅延が目立つようになりました!!
バイトサイズが大きくなるにつれて遅延が大きくなってしまうようですね!!
しかも、jpgからbmpにencodeを変換すると、
数秒の遅延が発生してしまい、ビデオとしては、、、使い物にならないですね😅
制御が単純で分わかりやすいのですが、ちょっと使うシーンは限定されてしまう気がします。
使うとしても制限を守った使い方が必要そうですね。。
pythonでのネットワークサーバ構築とsocket通信
今回はpythonでのtcp通信についてまとめておこうと思います!!
ちょっとやりたいことがあって調べていたので、それをまとめておくことが目的。
■socket通信とは?
socket通信とは、サーバとクライアントを仮想的な接続により結んで構成された環境のことを言います。
具体的には、インターネットはTCP/IPと呼ぶ通信プロトコルを利用しますが、そのTCP/IPを プログラムから利用するには、プログラムの世界とTCP/IPの世界を結ぶ特別な 出入り口が必要となります。
その出入り口となるのがソケット (Socket)であり、TCP/IPのプログラミング上の大きな特徴となっています。
このため、TCP/IP通信をソケット通信と呼ぶこともあります。
■環境
今回の構成はこちら。
ネットワークサーバをRaspberry Pi側に構築し、クライアントをwindows PCを用いました。
(逆の方がよかったかも。。。)
今回はpythonを用いるのですが、バージョンはこちらの通りです。
・windows PC側Pythonバージョン:3.7.4
・Raspberry Pi側Pythonバージョン:3.7.3
■ネットワークサーバ構築
まずはネットワークサーバの構築を行います!!
socket通信を行うためのネットワークサーバの構築を行うにあたり、
"socketserver"と"socket"が必要になるのであらかじめ、
pip install pycopy-socketserver or pip3 install pycopy-socketserver
pip install sockets or pip3 install sockets
でインストールを行っておきます。
ネットワークサーバ構築のコードはこちら。
import socketserver import socket class TCPHandler(socketserver.BaseRequestHandler): def handle(self): print(self.request.recv(1024).strip().decode()) self.request.send(("hello world").encode("utf-8")) HOST = 'hostを設定' PORT = ポート番号を設定 socketserver.TCPServer.allow_reuse_address = True server = socketserver.TCPServer((HOST, PORT), TCPHandler) try: server.serve_forever() except KeyboardInterrupt: pass server.shutdown() sys.exit()
server = socketserver.TCPServer((HOST, PORT), TCPHandler)
でサーバの初期設定を行い、
server.serve_forever()
でサーバとして起動・常駐させます。
そしてデータを受信すると、
def handle(self): print(self.request.recv(1024).strip().decode()) self.request.send(("hello world").encode("utf-8"))
がコールされます。
受信されたデータはバイト列になっているため、
self.request.recv(1024).strip().decode()
のようにデコードしております。
さらに、送信するデータもバイト列に変換する必要があるので、
("hello world").encode("utf-8")
というように文字列をエンコードしてから送信しています。
※今回はhello worldを固定で送信するようにしています。
■クライアント側構築
クライアント側では"socket"が必要になるのであらかじめ、
pip install sockets or pip3 install sockets
でインストールを行っておきます。
そして、、、コードはこちら。
import socket HOST = 'hostを設定' PORT = ポート番号を設定 sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM) sock.connect((HOST,PORT)) sock.send(('Hello Raspberry').encode("utf-8")) receivedstr=sock.recv(1024) print(receivedstr.decode())
まずは初期設定!!
sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM) sock.connect((HOST,PORT))
こちらに記載されているのですが、今回はTCPで通信したかったのでSOCK_STREAMを設定。
https://qiita.com/__init__/items/5c89fa5b37b8c5ed32a4
そして、
sock.send(('Hello Raspberry').encode("utf-8"))
でサーバへバイト列を送信。
今回はHello Raspberryの文字列をバイト列にエンコードして送信しています。
そして、
receivedstr=sock.recv(1024)
により受信したデータをreceivedstrに格納。
データはバイト列なので、文字列にデコードしてprintでログ出力しております。
■動作確認
始めにサーバ側を起動させた後、クライアント側でコードを実行すると、
【サーバ側】
Hello Raspberry
【クライアント側】
hello world
がコマンドプロンプト上に表示されればOKです!!
■最後に
今回の技術を応用してやりたいことが実現出来ました!!
やりたいことが出来て満足😆
後で、応用してできたこともまとめておこうと思います!!
Reactでアニメーション付きリストを表示
今まで作成したアプリやコードの整理真っただ中!!
今年中に終わるかな?🤣
そこで、以前作成したポートフォリオ(なのか)??を整理しつつ少しレイアウトを変更したので、
そこで使用したアニメーション付きリストについてまとめていきたいと思います!!
■事前準備
Reactにてモジュールにアニメーションを付けるために、React Poseを用います。
React Poseはこちらの通り、色々なアニメーションを付与させることができるようになるライブラリとなります。
https://popmotion.io/
このReact Poseをインストールするためにこちらを実行!!
sudo npm i react-pose
これで事前準備が完了です。
■リストへのアニメーション追加
では本題のアニメーションを付与していこうと思います!!
リストにアニメーションを付与するためのコードはこちらになります。
const sidebarProps = { open: { x: '10px', delayChildren: 300, staggerChildren: 100, }, closed: { delay: 500, staggerChildren: 20, x: '-100%' } }; const itemProps = { open: { opacity: 1, y: 0 }, closed: { opacity: 0, y: 10 } }; export default class TopPage extends Component { constructor (props) { super(props); this.state = { isOpen: false, }; } toggle = () => this.setState({ isOpen: !this.state.isOpen }); SelectApp = () =>{ return( <div width="250px"> <button onClick={this.toggle} className="asideSelectButton">Click Here !!</button> <SidePanel onClick={this.toggle} className="sidebar" pose={this.state.isOpen ? 'open' : 'closed'} > <Item className="item" value="WebApp">Webアプリ</Item> <Item className="item" value="ImageApp">画像処理</Item> <Item className="item" value="Python">python</Item> <Item className="item" value="Golang">go言語</Item> <Item className="item" value="MachineLearn">機械学習</Item> </SidePanel> </div>) } }
さらに、cssはこちらのようにしました。
.sidebar{ width:320px; font-size: 30px; background-color: aqua; } .item{ width:200px; padding-bottom: 5px; display: inline-block; padding: 0.5em 1em; text-decoration: none; border-radius: 30px; color: #ffffff; background-image: linear-gradient(45deg, #FFC107 0%, #ff8b5f 100%); box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.29); border-bottom: solid 3px #c58668; } .item:active { -webkit-transform: translateY(4px); transform: translateY(4px); box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.2); border-bottom: none; } .asideSelectButton { width:300px; margin-top:20px; margin-left:10px; font-size: 30px; display: inline-block; padding: 0.5em 1em; text-decoration: none; border-radius: 4px; color: #ffffff; background-image: linear-gradient(#6795fd 0%, #67ceff 100%); box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.29); border-bottom: solid 3px #5e7fca; } .asideSelectButton:active { -webkit-transform: translateY(4px); transform: translateY(4px); box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.2); border-bottom: none; }
細かい紹介の前にまずは動きから。
この"Click Here!!"を押下すると、
toggle = () => this.setState({ isOpen: !this.state.isOpen });
が呼び出されてフラグが立ちます。
すると、
pose={this.state.isOpen ? 'open' : 'closed'}
により、poseにopenがセットされます。
open/close時の動作は、
const sidebarProps = { open: { x: '10px', delayChildren: 300, staggerChildren: 100, }, closed: { delay: 500, staggerChildren: 20, x: '-100%' } }; const itemProps = { open: { opacity: 1, y: 0 }, closed: { opacity: 0, y: 10 } };
により定義されており、
open時にはリストが表示、close時にはリストが非表示の動作になります。
再度ボタンやリストを押下すると、
toggle = () => this.setState({ isOpen: !this.state.isOpen });
が再度呼びされ、フラグが落ちてclose動作が走ります。
■最後に
整理するのが思ったより大変です。。しかもこうやって新しいことにも挑戦しているから尚更😅
今年中に整理終わるといいな!!
Raspberry PiへのGoCVインストール
以前LinuxへのGoCVへのインストール手順についてまとめました。
elsammit-beginnerblg.hatenablog.com
こちらの手順を元にRaspberry PiへOpenCVをインストールしようとしたのですが、、、
少しハマったのでハマった箇所や解決策についてまとめておこうと思います!!
■環境
・デバイス:Raspberry Pi 4
・OS:Raspbian GNU/Linux 10 (buster)
・GoCV:go version go1.15.6 linux/arm
【国内正規代理店品】Raspberry Pi4 ModelB 4GB ラズベリーパイ4 技適対応品【RS・OKdo版】 新品価格 |
■ハマった箇所
以前まとめた手順通り、
go get -u -d gocv.io/x/gocv
を実行の上、
export PKG_CONFIG_PATH="/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH"
にてパスを通し、/usr/local/lib/pkgconfig配下のopencv4.pcを下記の通り編集します。
※もしopencv4.pcが存在しなければ新規で作成。
prefix=/usr/local exec_prefix=${prefix} includedir=${prefix}/include libdir=${exec_prefix}/lib Name: opencv4 Description: The opencv library Version: 4.0.0 Cflags: -I${includedir}/opencv4 Libs: -L${libdir} -lopencv_aruco -lopencv_bgsegm -lopencv_bioinspired -lopencv_calib3d -lopencv_ccalib -lopencv_core -lopencv_datasets -lopencv_dnn -lopencv_dnn_objdetect -lopencv_dpm -lopencv_face -lopencv_features2d -lopencv_flann -lopencv_fuzzy -lopencv_gapi -lopencv_hfs -lopencv_highgui -lopencv_img_hash -lopencv_imgcodecs -lopencv_imgproc -lopencv_line_descriptor -lopencv_ml -lopencv_objdetect -lopencv_optflow -lopencv_phase_unwrapping -lopencv_photo -lopencv_plot -lopencv_reg -lopencv_rgbd -lopencv_saliency -lopencv_shape -lopencv_stereo -lopencv_stitching -lopencv_structured_light -lopencv_superres -lopencv_surface_matching -lopencv_text -lopencv_tracking -lopencv_video -lopencv_videoio -lopencv_videostab -lopencv_xfeatures2d -lopencv_ximgproc -lopencv_xobjdetect -lopencv_xphoto
そして、、、
cd $GOPATH/src/gocv.io/x/gocv sudo make install
を実行!!
しばらくしたところビルドエラー。。。
ログを確認したところ、
../../../../gocv.io/x/gocv/core.go:2008: type [1073741824]C.struct_Point larger than address space ../../../../gocv.io/x/gocv/core.go:2008: type [1073741824]C.struct_Point too large
といったエラーが発生。
■解決策
先ほどの指摘されたコードは、
tmpslice := (*[1 << 30]*C.char)(unsafe.Pointer(strs.strs))[:length:length]
となります。
どうやら32bit OSである場合、
1 << 30
だとアドレスの範囲を超えてしまう(オーバー)してしまうようです。
このためこちらを、
1 << 20
に変更!!
そして再度、
sudo make install
を実行!!
問題なくエラーが発生せずにインストール成功しました。