2017年7月5日 星期三

C++ 如何辨識代碼是在 gcc 上面跑還是 vc 上跑

C++ 如何辨識代碼是在 gcc 上面跑還是 vc 上跑

有些時候我們會需要能夠識別到底是在 gcc 上還是 visual Studio 上跑,畢竟兩者之間相容性還是有很大區別的,可以利用 Macro 來偵測。
如以下範例,把代碼打在裡面就自然會在正確的編譯器上運行了。
#if defined(_MSC_VER) 
   /* VC */
#endif

#if defined(__GNUC__)
   /* gcc */
#endif

2017年7月4日 星期二

從零開始使用 STM32 F469I 燒錄測試程式

從零開始使用 STM32 F469I 燒錄測試程式

大多數的時候我發現其實真正不能起手的是不知道怎麼燒錄!不知道為什麼網路上大多都只教學如何改代碼代碼是什麼意思,如果今天給你一塊板子你該怎麼辦?
這篇文章主要就是介紹如何從零開始,你手上只有板子你什麼都沒有怎麼辦?

預裝軟體

  1. MDK523.EXE (Keil uVision5)
    可以從官方下載免費版的,可以用只是會限制上傳大小
  2. ST-Link
    可以從板子上的網址連過去下載
  3. Keil.STM32F4xx_DFP.2.9.0
    可以直接從uVision5內更新或下載
  4. 範例代碼
    可以從板子上的網址連過去下載

uVision5

到官方下載,可以直接用,免費版本有限制。
官方網址:http://www2.keil.com/mdk5/
幫你點好了懶人包:http://www2.keil.com/mdk5/install

板子上會有一個網址,連過去可以下載,大概會長這個樣子

幫你打上來大概F4系列都是同一個
網址:http://www.st.com/stm32f4-discovery

接下來找到你自己的型號,以這邊範例是這個

拉到最下面這裡只是版本差異都可以

下載,不過會要你填一些資訊,之後會把載點寄到信箱,記得不要亂填

載好之後直接安裝,看你電腦幾位元的就安裝什麼

Keil.STM32F4xx_DFP

這個是keil裡面的套件,可以直接線上更新,記得要連網不然會看不到。
需要什麼就選什麼裝就好,還蠻大的要花不少時間慢跑
到這邊環境已經架設好可以跑瞜~
手動下載離線包可以到下面連結找到相對應的板子型號,一樣在上方的畫面左上角 File 點進去之後按加入,可以不用解開壓縮檔直接按加入。
http://www.keil.com/dd2/pack/

範例代碼

在剛剛 ST-Link 下載的網址
這裡整個F4系列的都共用的,都包含進去了
解壓縮之後開啟這個位置
STM32Cube_FW_F4_V1.16.0\Projects\STM32469I-Discovery\Examples
粗體型號必須選自己的板子,這個型號盒子上有寫,有些型號版本有細微的差異,板子本身沒有打印。
這裡進來就是各項使用的範例,我們使用最簡單的GPIO當測試,可以從板子上內建的按鈕與LED燈測試燒錄成功。
進來之後選擇 GPIO\GPIO_EXTI\MDK-ARM MDK-ARM是寫給我們剛剛安裝的軟體用的範例代碼。

執行

開啟剛剛的GPIO測試
接下來先按編譯,這裡第一次要按全部編譯,會比較久,第二次如過只動一份檔案可以按他左邊的只重新編譯當前文件,這樣比較省時間。
編譯完畢之後執行,執行要手動跑一下程序左邊四個自己選,跑完結束的地方像圖中那樣,接下來按一下板子藍色的按鈕,翻到正面看LED會跟著你按的時候做出變化。
如果想直接讓他跑到底直接看結束,可以翻板子後面reset按一下就會自動跑完了,不過跑完就不能重來了,要除錯再按 ctrl+f5 重跑一次就好了。

參考

2017年6月23日 星期五

筆電安裝 SSD (M2) 之後如何選擇以 SSD (M2)開機

筆電安裝 SSD (M2) 之後如何選擇以 SSD (M2)開機

記得新硬碟預設都是MBR要改成GUID才可以正常使用,改變的方式直接在windows內修改即可。
另外請不要做4K對齊,大多數的網站都說要但那其實沒必要,只要使用windwos的光碟或USB把分割區砍光在重新切割(會切好幾份正常的)就已經對齊;真正需要對齊的是XP,XP的安裝光碟不會幫你對齊,必須手動執行對齊。
還有一堆優化SSD的手續呀~千萬不要,現在都2017了~請相信微軟是一家有能力的公司,放心交給他都已經幫你做好了。不過如果你是在XP還是有必要要自己做。

選擇硬碟

如果不想移除舊系統可以留著,有個兩個方式可以選擇使用M2開機,一種是硬碟拆了只留SSD它會自動幫你選到SSD開機,在接上原本的硬碟。
如果需要臨時開到別的硬碟,去BIOS開啟F12選單,可以選硬碟
另一種是你不能拆,然後又偏偏他是開你的HDD那你只好自己建立開機選單了,建立方式也不難,進去BIOS先設定密碼(這是必要的才能啟用功能),然後再設定密碼那裏就有一個瀏覽EFI開機檔,檔案並不多你就瀏覽一下很容易可以找到的,忘了拍照。

使用MBR硬碟

很多網站建議應該使用MBR,千萬不要這會造成不少後果…
已知可能造成關機會黑屏然後電源沒切,解決方式是去電源關閉快速啟動。這個舉動會大大減緩開機速度,沒辦法使用混合開機。
已經裝了沒事就好了,開機慢一點還是可以用。

2017年6月21日 星期三

[圖文] OpenCV 3.4.1 安裝配置在 Visual Studio 2017

[圖文] OpenCV 3.4.1 安裝配置在 Visual Studio 2017


1. 新版的 Visual Studio 2022 + OpenCV490 可以參考新文章https://charlottehong.blogspot.com/2024/02/opencv-490-win11-visual-studio-2022.html







2. Visual Studio 2019 + OpenCV401 可以參考新文章
https://charlottehong.blogspot.com/2019/02/opencv-401-visual-studio-2019.html

正文開始

先到官方下載這兩項軟體 (點擊有連結)
關於 Visual Studio 2017 如何安裝可以參考 https://charlottehong.blogspot.com/2018/09/c-visual-studio-2017.html
建議直接解壓縮到C槽,本文範例即直接解壓縮到C


文件說明

build文件是官方已經幫你預先編譯好的檔案,開進去
C:\opencv\build\x64\vc15\bin
可以看到vc15 的字樣,這是給 visual studio 2017 用的。
總而言之會用到的只有
  • C:\opencv\build\include
  • C:\opencv\build\x64\vc15


部屬 OpenCV

首先只要做一次就好的是
  • 系統環境變數加入 bin 路徑
編譯器大概需要三個步驟(每次第一次開新專案)
  • 編譯器加入 include 路徑
  • 編譯器加入 lib 路徑
  • 編譯器加入 lib 檔案

環境變數(說明文字在圖下)

搜索一下你的電腦環境變數或系統內容都可以(也可以直接對著本機按右鍵內容)
(點擊放大)位置是:C:\opencv\build\x64\vc15\bin
如果在設定環境變數之前就已經先打開 Visual Studio 的話,需要重新啟動 Visual Studio ,沒有重開編譯的時候會出現 “找不到**.dll檔案”
標記一下蠻常出現的錯誤
LNK1104 無法開啟檔案 'opencv_worldXXXd.lib'
這個是環境變數這個步驟做錯了

設定編譯器

打開新專案
選擇傳統式精靈,專案名稱就隨意打一個不影響
打勾空白專案,(這裡其實可選,文章為方便撰寫使用空白專案)
再來對著專案按右鍵新增檔案
可以改名字,這邊我就直接按新增了
再來要進入設定裡面設置,留意一下紫色的框框待會會用到
截圖截錯了,以下 紫色框框要選 x64 模式  (OpenCV 提供的預編檔案只有x64)
截圖截錯了,以下 紫色框框要選 x64 模式  (OpenCV 提供的預編檔案只有x64)
進來之後對照一下紫色框框,兩個要一樣才有用(總共會有4種組合)
貼上include的路徑:C:\opencv\build\include
這裡貼上 lib 的路徑:C:\opencv\build\x64\vc15\lib
一樣留意一下紫色的框框
這裡需要指定引入那些 *.lib 檔案
我們進來opencv的文件裡面看
根據你的模式設定(留意紫色框框)
好了之後貼上測試代碼
/**********************************************************
Name :
Date : 2016/05/29
By   : CharlotteHonG
Final: 2016/05/29
**********************************************************/
#include <iostream>
#include <opencv2/opencv.hpp>

using namespace cv;

int main(int argc, char const *argv[]) {
    /* 畫布 */
    Mat img(270, 720, CV_8UC3, Scalar(56, 50, 38));
    /* 直線 */
    line(img, Point(20, 40), Point(120, 140), Scalar(255, 0, 0), 3);
    /* 實心方塊 */
    rectangle(img, Point(150, 40), Point(250, 140), Scalar(0, 0, 255), -1);
    /* 實心圓 */
    circle(img, Point(330, 90), 50, Scalar(0, 255, 0), -1);
    /* 空心橢圓 */
    ellipse(img, Point(460, 90), Size(60, 40), 45, 0, 360, Scalar(255, 255, 0), 2);
    /* 不規則圖形 */
    Point points[1][5];
    int x = 40, y = 540;
    points[0][0] = Point(0 + y, 50 + x);
    points[0][1] = Point(40 + y, 0 + x);
    points[0][2] = Point(110 + y, 35 + x);
    points[0][3] = Point(74 + y, 76 + x);
    points[0][4] = Point(28 + y, 96 + x);
    const Point* ppt[1] = { points[0] };
    int npt[] = { 5 };
    polylines(img, ppt, npt, 1, 1, Scalar(0, 255, 255), 3);
    /* 繪出文字 */
    putText(img, "Test Passed !!", Point(10, 230), 0, 3, Scalar(255, 170, 130), 3);
    /* 開啟畫布 */
    namedWindow("OpenCV Test By:Charlotte.HonG", WINDOW_AUTOSIZE);
    imshow("OpenCV Test By:Charlotte.HonG", img);
    waitKey(0);
    return 0;
}
留意一下紫色框框是不是跟你剛剛設定的一樣 (這邊我已經發現錯了改回x64)
如果做到這邊才發現跟我一樣選錯了,要退回去include路徑那步重作
設定裡面 x86->x64 改了全部會歸零…

運行

設定好之後直接按F5運行吧~~
出現找不到 dll 檔案,重新啟動一下 Visual Studio 2017 。


其他

如果需要完整的OpenCV功能,比如說 SIFT 等這些實作需要自己重新編譯,重新編譯可以參考這篇站內文,手動編譯原始檔的方法。
http://charlottehong.blogspot.com/2017/07/opencv-320-contrib-visual-studio.html

C / C++ Bitmap(BMP) 圖檔讀寫範例 與 檔頭詳細解析

C / C++ Bitmap(BMP) 圖檔讀寫範例 與 檔頭詳細解析

C/C++ 純軟體讀取修改 bitmap 檔案完整介紹如下,文末附上詳細的原始碼可以參考。
例外也有如何讀取灰階圖gray與彩圖RGB的問題、以及解析度不為4倍數的時候如何處理4byte位元對齊,並且寫成一個萬用的函式,代碼開源(source code)可在文末下載,可直接直接編譯並執行程式碼不需外掛函式庫。

介紹

BMP圖檔大致分為四大部分下面會依序解說
  • 檔案檔頭(14byte)
  • 圖片檔頭(40byte)
  • 調色盤(1024byte)
  • Raw檔
這裡的byte看成是一個字元(char),如果是字元與Raw檔讀取就順著讀而已,比較特別是數字讀取的時候要一起讀;比如說根據表頭某4byte是一組的他們是 00 FF 01 0A 那你要反著讀變成 0A 01 FF 00 而不是直接讀取。(注意看細微變化 01 不會變成 10)
有興趣的可以查查這個詞 Endianness:https://goo.gl/xu9uYB
建議除錯的使用二進位軟體查看,比如說 HxD 來看(阿榮載點)

檔案檔頭(14byte)

範例代碼:(占用位元可以從代碼上看到)
struct BmpFileHeader{
    uint16_t bfTybe = 0x424D;
    uint32_t bfSize;
    uint16_t bfReserved1 = 0;
    uint16_t bfReserved2 = 0;
    uint32_t bfOffBits = 54;
};
其中有寫數值等於多少的地方是 C++的類內初始化。C要刪除等號與數值才能編譯。
第一個 bfTybe 比較特別的是他是BM,你也可以寫成 unsigned char type[2]= {'B', 'M'};,他就是固定的識別代碼,標準規定。
再來 bfSize 是指檔案大小,就是包含上述全部資料大小,這也會是你直接對BMP右鍵內容看到的容量大小。
再來 bfReserved 兩項直接填0就好了,不影響一般操作,詳細規格可以參考維基百科。
再來最後面 bfOffBits 的54是固定的就是14+40,不過如果你是用灰階圖記得要加上1024(調色盤占用的)。
類內初始化:C++11標準才可以使用
使用 g++ 加上 -std=c++11 參數即可,如 g++ -std=c++11 source.cpp
Visual Studio 2017 以上就直接是 C++11 了,不需要設置。

圖片檔頭(40byte)

範例代碼:(占用位元可以從代碼上看到)
struct BmpInfoHeader{
    uint32_t biSize = 40;
    uint32_t biWidth;
    uint32_t biHeight;
    uint16_t biPlanes = 1; // 1=defeaul, 0=custom
    uint16_t biBitCount;
    uint32_t biCompression = 0;
    uint32_t biSizeImage = 0;
    uint32_t biXPelsPerMeter = 0; // 72dpi=2835, 96dpi=3780
    uint32_t biYPelsPerMeter = 0; // 120dpi=4724, 300dpi=11811
    uint32_t biClrUsed = 0;
    uint32_t biClrImportant = 0;
};
  • biSize 檔頭的大小
  • biWidth 圖片的寬
  • biHeight 圖片的長
  • biBitCount 位元數,彩圖要設RGB 8*3=24,灰階圖設8
  • biSizeImage 指的是總共有幾個像素,如果是彩圖有RGB,除了長x寬還要再 *3
    實測有些軟體存出來的bmp的biSizeImage會是0,建議用長x寬自己算像素值。
  • biClrUsed 指的是調色盤的顏色數,彩圖設 0 即可,灰階圖要自訂調色盤要設 256
  • PelsPerMeter指的是密度,一般軟體好像也不看都是設0即可,windwos電腦預設是96dpi,大概就差別在你把這張圖拉上PPT上設越高會縮的越小。

調色盤(1024byte)

這個是可選的不一定會有,圖是RGB彩色不用留空(如00),直接就是沒有才是正確的。
如過圖片是灰階圖你就要自己補上調色盤,調色盤意思其實也很簡單就是 00 00 00 00~ FF FF FF 00 而已,這是因為灰階圖只需用一個byte表示,但是整張BMP需要用 RGB 表示,所以調色盤的功用就是把看到的RAW檔,就比如看到 00 變成 00 00 00 看到 FF 變成 FF FF FF
總的來說意思是自訂規則從 “單一通道” 解析出 “RGB三通道”。
你可以一次做好整份調色盤在寫入,也可以用for迴圈寫入,數量不多不會太損效能可以用for比較整潔些,範例如下寫法。
for(unsigned i = 0; i < 256; ++i)
    img << uch(i) << uch(i) << uch(i) << uch(0);

Raw檔

比較特別的是讀取的方式是從圖的左下角開始往右邊上面讀取,而且數據是BGR反過來的,並且他們的行會對齊4byte,如果圖片是40x42那麼你寫入的時候要寫成40x44不足的2位元補空白0。
bmp 4bit 對齊的公式代碼如下
size_t RealWidth = Width * bits/8;
size_t alig = (RealWidth*3)%4;
算出來是2的話就是說每行的結尾要塞 2 個 char(0) 就是 0x0000
算出來是4的話就是說每行的結尾要塞 3 個 char(0) 就是 0x000000
值得注意的是公式要針對不同的位元的圖片做不同的處理
可以想像成假設同一張3x3的圖片那麼,對黑白圖來說就是每行結尾要補1個空白,對於彩色的圖來說每個點個別有RGB,也就是實際寬度總共是9個點,9個點的話4位元對齊就需要補3個空白。
總結一下萬用公式就是 圖的實際位元寬度*3 % 4 這樣。

注意

  1. 灰階圖要多寫調色盤,有三個地方要更動
    FileHeader 的 size        +1024
    FileHeader 的 headSize    +1024
    InfoHeader 的 size        +1024
    InfoHeader 的 ncolours    =256
    
  2. 讀RAW檔的時候(也就是像素值),檔案指標要跳過調色盤(建議是直接抓 headSize 比較省事)。
  3. 讀寫RAW檔區域的時候,記得跳過4byte對齊,對齊算法是
    size_t alig = ((width*bits/8)*3) % 4;
    

範例 SourceCode

C++的版本多了不少功能,後來維護到一半荒廢了QQ 留下不少測試代碼~
還有許多未完成的功能~覺得好用的話可以在這或gihub上留言~
建議其他功能或是bug回報也好,有人留言可能哪天就有動力大改版了XDD