2016年5月29日 星期日

C++ OpeCV 2.4.13 for Windows MinGW g++ [在 window上使用 MinGW g++ 編譯 opencv]

C++ OpenCV 2.4.13 for Windows MinGW g++

在 window上使用 MinGW g++ 編譯 opencv

前言

這幾天想用 MinGw 編譯 OpenCV,資料有些零散中文也不多
花了不少時間把搜尋資料,做好之後有順便做了一個懶人包
如果新手剛學,建議可以直接用懶人包就好了
懶人包已經簡化到只需按兩個安裝按鈕,就這樣而已
還有編譯時只要把g++替換成cv2就好了
cv2 file.cpp -o file 就這樣,幫你處理掉重複又很長的代碼了

安裝

檔案:https://goo.gl/2HfaPV
測試程式碼:https://goo.gl/fjcY9P
以下是安裝步驟:(建議使用預設位置)
1.開啟 MingGW AutoInstall
2.開啟 OpenCV2413 AutoInstall
3.開啟 OpenCV_Tester
很神奇的就安裝完畢瞜~
注意:如果已經安裝過MingGW,請移除在安裝(環境變數也要移除)
程序並沒有防呆會處理這個狀況,會出問題的。
看看有沒有跳出測試通過,有的話就可以開始使用了
看到這個就成功摟

懶人包裡面有sublime text3的編譯文檔,
可以直接 CTRL+B 編譯

如何以命令編譯C++檔案

懶人包

如何編譯指令在 OpenCV_Tester 內有說明
終端機輸入 cv2 souce.cpp -o souce 這樣即可

命令

原本的代碼則是:(這裡是依照我的檔案路徑)
g++ -I"C:\OpenCV\include" -I"C:\OpenCV\include\opencv" -I"C:\OpenCV\include\opencv2" -L"C:\OpenCV\MinGw_64\lib" souce.cpp -lopencv_core2413 -lopencv_highgui2413 -lopencv_imgproc2413 -o souce& souce.exe
如果是安裝我的懶人包,可以使用 cv2 來替換
cv2 souce.cpp -o souce

重新編譯OpenCV檔案

如果你要自己編譯其實也沒到多複雜只是很多設定要自己來別漏掉就好了
跟linux一樣,cmake編譯,然後產出的文件在依照規定對應就完成瞜
有興趣的可以參考:http://goo.gl/f7r2C7
還有:http://goo.gl/X1S0P

2016年5月22日 星期日

Arduino Uart 互傳字串 與 字串處理 依特定符號切割

Arduino Uart 互傳字串 與 字串處理 依特定符號切割

兩台arduino要互傳

兩台arduino要互傳字串的話這裡寫一個範例
注意
  • 兩台不要形成死循環,[A給B] [B再給A] [然後A再給B]…..
  • 會新建一個uart通道,而不是使用預設的
通道請參考程式碼頂端的宣告
已經盡量用不會混淆的方式註解
要表達兩台人稱問題其實有些困難XD

字串切割

字串切割的話這裡也有一個範例,可以自訂格式
比如說你想要船 0,1,2,3 你想把他們依照逗號存到陣列內
也可以依照其他符號,由你自己設定
裡面忘記放使用範例了
大致來說是這樣的
(第一個放字串,第二個放符號)
str_split(const char* str, const char* sp)
char str="1,2,3";
int *ptr=0;                  //注意星號
ptr=str_split(str,",");  //逗號可以任意修改成你要的形式
println(ptr[0]);           //返回為一個陣列的指標,可以直接使用下標[]呼叫

釋放記憶體

因為是動態陣列,結束時要釋放記憶體
(動態陣列意思就是回便你字串都常都可以適應)
free(ptr);
不過arduino是沒有結束點的,無限循環,
依照你的程式設計去選擇,這裡也不好舉例子說明
通常不放也不會造成問題,新手可以先暫時放置著
完成功能後再去想辦法解決這個問題。

為什麼要使用 C++ 而不要用 C

接觸 [C++] [1個月]
覺得比較重要的概念 (入門)
我在寫C的時候就發現一些問題了
[雙向鏈結](https://goo.gl/XGvMhh)
-
1.如果你寫過一堆副程式,你就會發現資料的傳遞
真的很麻煩,不得不用結構去組成
一堆變數你根本沒辦法搞清楚誰是誰
-
2.再來就是傳遞時候,因為不是在同一個區域(不同副程式)
記憶體不共用,變數沒辦法直接修改
比如說你有一個 i=10; 你沒辦法 add(int i){...}
就修改 i 的數值,這會造成不少困擾
(比如說沒辦法將功能拆到函式內
拆不出去只能寫在主程式,寫多了
等你回頭一看的時候你就知道完蛋了)
逼不得已只能用指標去操作
int x=5, *i=&x; add(int *i){...}
如此一來就能直接改了
-
3.即便滿足以上條件,還是有個大問題
有些根本無關聯的變數你不想塞在
同一個結構內(無關聯的到時候亂掉)
就變成每個副程式都要導入一堆參數
typedef struct struct _node node;
struct struct _node {...};
void fun(node a, int a, int b, int c, int d, int e ){...}
這個就不好解啦XD 乖乖一個一個打
-
如果用類別去寫,上述問題大多能改善
1. 他本身就有點類似結構概念可以放很多變數
2. 在同一個類別內不同副程式仍可以直接存取 this->a
3. 都直接存取了,當然就不用導入了
(即便不同類別還有[朋友], [繼承]的方法可以共用)
-
比較不一樣的地方是類別的使用可以用 點
class demo{...};
demo temp(0); //初始數值0
temp.ad(1).ad(2).ad(3); // 0+1+2+3=6
temp.pri(); //印出
看出來了嗎如果是傳統副程式
1. 上述做法大概要分行了
int temp=0,*p=&temp;
ad(p,1);
ad(p,2);
ad(p,3);
printf(...);
2. 還有一種情況全部都塞在裡面
[ad(ad(ad()));]這真的會害人看不懂XDD
-
阿對了還有一個很重要的概念
不要花太多時間在沒有報酬的程式上
每一次的寫作,考慮以後是否能重複使用
然後就這樣把她留下來,不要同一個坑跌兩次
要嘛就花很多很多時間一次弄到最好
要嘛就隨便剪剪貼貼湊出功能,管他有沒有排版
前者你賺到了一份完整可以重複使用程式碼,
而且不用擔心未來的自己看不懂,
後者你賺到時間,把時間花在有用的事情上吧
畢竟一次性的功能也沒人會去看程式碼的XDD