2018年3月12日 星期一

opencv 特徵點匹配 ORB、SURF、SIFT 以及 RANSAC 過濾的範例代碼

opencv 特徵點匹配 ORB、SURF、SIFT 以及 RANSAC 過濾的範例代碼

void sift1(string name1, string name2){
    Mat img_1 = imread(name1, CV_LOAD_IMAGE_GRAYSCALE);
    Mat img_2 = imread(name2, CV_LOAD_IMAGE_GRAYSCALE);
    Mat img_matches;
    Mat img_test;

    if(!img_1.data || !img_2.data){
        cout << "opencv error" << endl;
        return;
    }

    // cv::Ptr<Feature2D> f2d = xfeatures2d::SIFT::create();
    // cv::Ptr<Feature2D> f2d = xfeatures2d::SURF::create();
    cv::Ptr<Feature2D> f2d = ORB::create();

    //-- Step 1: Detect the keypoints:
    std::vector<KeyPoint> keypoints_1, keypoints_2;
    f2d->detect(img_1, keypoints_1);
    f2d->detect(img_2, keypoints_2);

    img_test = img_1;
    drawKeypoints(img_1, keypoints_1, img_test, Scalar::all(-1));
    imshow("Keypoints", img_test);

    //-- Step 2: Calculate descriptors (feature vectors)    
    Mat descriptors_1, descriptors_2;
    f2d->compute(img_1, keypoints_1, descriptors_1);
    f2d->compute(img_2, keypoints_2, descriptors_2);

    //-- Step 3: Matching descriptor vectors using BFMatcher :
    BFMatcher matcher;
    std::vector< DMatch > matches;
    matcher.match(descriptors_1, descriptors_2, matches);
    drawMatches(img_1, keypoints_1, img_2, keypoints_2,
        matches, img_matches, Scalar::all(-1), Scalar::all(-1),
    std::vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);
    imshow("Matches", img_matches);

    //-- Quick calculation of max and min distances between keypoints
    double max_dist = 0; double min_dist = 100;
    for(int i = 0; i < descriptors_1.rows; i++){
        double dist = matches[i].distance;
        if(dist < min_dist) min_dist = dist;
        if(dist > max_dist) max_dist = dist;
    }
    printf("-- Max dist : %f \n", max_dist);
    printf("-- Min dist : %f \n", min_dist);
    //-- Draw only "good" matches (i.e. whose distance is less than 3*min_dist )
    std::vector< DMatch > good_matches;
    for(int i = 0; i < descriptors_1.rows; i++){
        if(matches[i].distance < 3 * min_dist)
            good_matches.push_back(matches[i]);
    }
    drawMatches(img_1, keypoints_1, img_2, keypoints_2,
        good_matches, img_matches, Scalar::all(-1), Scalar::all(-1),
        std::vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);
    imshow("Good Matches", img_matches);

    vector<DMatch>& Input_matches = matches; // good_matches, matches
    // get feat point
    vector<Point2f> featPoint1;
    vector<Point2f> featPoint2;
    for(size_t i = 0; i < Input_matches.size(); i++){
        //-- Get the keypoints from the good matches
        featPoint1.push_back(keypoints_1[Input_matches[i].queryIdx].pt);
        featPoint2.push_back(keypoints_2[Input_matches[i].trainIdx].pt);
    }
    // get Homography and RANSAC mask
    vector<char> RANSAC_mask;
    Mat Hog = findHomography(featPoint1, featPoint2, RANSAC, 3, RANSAC_mask, 2000, 0.995);
    drawMatches(img_1, keypoints_1, img_2, keypoints_2,
        Input_matches, img_matches, Scalar::all(-1), Scalar::all(-1),
        RANSAC_mask, DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);
    imshow("RANSAC Matches", img_matches);

    waitKey(0);
}

2018年3月10日 星期六

Win10 ATI HD4850 4870 driver 正確運作 CCC 軟體

Win10 ATI HD4850 4870 driver 正確運作 CCC 軟體

先看結果 (右下角有當前時間)
AMD的官方已經直接表名說不支持不能用了,不過實際測試之後還是可以使用。
測試的系統是 Windwos10 1709,顯示卡有 HD4870 HD4855 HD4350 等三張。

安裝開始

要分開裝驅動與 catalyst control center 軟體

下載

要下載舊版的來用
目標下載 13.1 來使用
下載下來要先安裝
這個會先解壓縮到C曹的這個位置,先解壓縮(按上圖Install)
然後會跳出安裝選單如下圖,先不要按,重要的是目前已取得檔案等一下會用到。
到上圖這個畫面就先停著不要動

手動安裝驅動

打開工作管理員,快捷鍵是先按 Win+X 然後再按 M
選到剛剛的位置 (下面是預設)
C:\AMD\Support\13-1-legacy_vista_win7_win8_64_dd_ccc\Packages\Drivers\Display\W86A_INF
選中 C7 開頭的這個
然後就可以安裝了,安裝完成之後解析度就可以正常條了
要確認有沒有安裝可以查看驅動程式日期,13.1內附的驅動日期是2012.11,微軟提供的是2015版本的,要驅動CCC必須使用CCC內附的版本才可以。

CCC 驅動安裝

必須先安裝完驅動才可以,再來跳回來剛剛的CCC安裝介面可以按下一步了。
如果要開CCC,那驅動就要裝CCC附贈的同一個驅動版本。
這裡要選自訂然後取消驅動的打勾(因為剛剛已經安裝了)

(備註:我不是在同一台電腦做的,這台沒安裝卡,這裡才會不能取消打勾)
然後安裝完畢之後可能還會看不到,要重新啟動之後 CCC 開起來就可以調整細部選項了
比如說接上 HDMI 之後螢幕內縮編編有黑框,可以把縮放調為 0 就沒黑邊了
或者是接上 HDMI 之後顏色怪怪的偏白,也是驅動裡面調成全彩 RGB 就好了
經過測試後發現最新可安裝的版本為 13.4 版本,這個也可以順利驅動+開啟CCC,不過介面是英文版的。

2018年3月9日 星期五

Win10 一直自動清理縮圖,要重跑縮圖

Win10 一直自動清理縮圖,要重跑縮圖

貌似是更新到 1709 才這樣,我不確定是升級上還得bug還是全新安裝也會這樣,總而言之好像還蠻多人的,解決辦法只能停用這個功能。
1709之後多了自動清理緩存的功能,不過實際上如果SSD容量足夠並不建議時常清理,半年清理個一次就差不多了。

自動清理的設定位置

位置在 儲存空間 內,你可以直接在開始搜尋 儲存空間 就可以看到他
這個東西會自動清理,但是我已經將它關閉了,他還是不正常作用,時不時就給我清理一下,實在很惱人。
工作排程DiskCleanupSilentCleanup 強制關閉這個功能就會好了。
工作排程可以在開始欄打字搜尋找到。
找到他之後把它關閉吧,之後就不會再來煩你了~

Visual Studio IMAGE::BuildImage 錯誤

Visual Studio IMAGE::BuildImage

錯誤信息:
LINK : fatal error LNK1000: Internal error during 
IMAGE::BuildImage
先按上面的清除方案把暫存檔清掉,如果沒犯什麼引入的錯大概就好了
如果清掉還是不行,有可能是引入的問題
  1. A.cpp 引入 B.hpp 然後 B.cpp 又引入 A.hpp 互相卡住
  2. 盡量清除 .hpp 內的引入,寫到 .cpp 內
[1] 整理一下邏輯了,會互卡就很奇怪了~很容易出現在架構沒出來走一步算一步的情況
[2] 降低多餘的引用,如果寫在 hpp 內每個引用的檔案都會引用到
寫道 cpp 內的話需要置後,比如說一份檔案 A.hpp 內寫到了 vector ,那你在 A.cpp 的時候要這樣寫
#include <vector>
#include "A.hpp"
這樣就能編過了,不過也導致每個引入 A 的都要補 vector,如果是內建的比如說 vector、string 這些用到的機率也很高就寫吧;如果是自己寫的函式庫看有沒有方法,改個寫法避開,原則上能越少越好。

參考

2018年3月8日 星期四

Visutal studio 中的 git 同步失敗 Git failed with a fatal error

Visutal studio 中的 git 同步失敗

出現的訊息是這樣的:
在存放庫 C:\Users\hunan\source\repos\feat_fast 中於本機建立了認可 89194807
推送至遠端存放庫時發生錯誤: Git failed with a fatal error.
HttpRequestException encountered.
   �ǰe�n�D�ɵo�Ϳ��~�C
cannot spawn askpass: No such file or directory
could not read Username for 'https://github.com': terminal prompts disabled
Pushing to https://github.com/XXXX/ORB.git
我最後的解決辦法是開啟 git for windwos 中的 bash 然後 cd 到目錄位置,使用他來上傳
git push master origin
更新今天找到原因了,因為github改版了,在認證上有做調整
https://githubengineering.com/crypto-removal-notice/
VS是被引響到的範圍之一,更新VS到最新版本就好了,然後建議 git for windows 也更新一下到最新版。

參考

2018年3月7日 星期三

STM32F4 如何輕鬆的自訂 LED 任意腳位初始化 與 點亮

STM32F4 如何輕鬆的自訂 LED 任意腳位初始化 與 點亮

有鑑於官方預設語言是C,想要點亮LED要做的工作也是有點多行,寫個一兩個還不是什麼大事,寫個幾10個然後發現有錯要修改,就難過了。
前一陣子在PTT看到有人用 macro 在 C 上面弄出 STL ,仿物件實在很牛QuQ
雖然看不董細節怎麼做的,不過至少原理是解了的,依樣畫葫蘆刻了一個做練習
/**
  * @brief  LED initial Obj
  * @author None
  * @site   https://charlottehong.blogspot.tw/
  */
#define STATEMENT_(...)  do {__VA_ARGS__} while (0)
#define LED                                               \
struct HAL_LED{                                           \
  GPIO_TypeDef* port;                                     \
  uint16_t pin;                                           \
  GPIO_InitTypeDef  GPIO_InitStruct;                      \
}
#define GPIO_ENABLE(GPIO)                                 \
STATEMENT_(                                               \
  __HAL_RCC_##GPIO##_CLK_ENABLE();                        \
)
#define LED_init(self, GPIO, GPIO_PIN, state)             \
STATEMENT_(                                               \
  self.port=(GPIO);                                       \
  self.pin=(GPIO_PIN);                                    \
  __HAL_RCC_##GPIO##_CLK_ENABLE();                        \
                                                          \
  self.GPIO_InitStruct.Pin = self.pin;                    \
  self.GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;        \
  self.GPIO_InitStruct.Pull = GPIO_PULLUP;                \
  self.GPIO_InitStruct.Speed = GPIO_SPEED_FAST;           \
                                                          \
  HAL_GPIO_Init(self.port, &self.GPIO_InitStruct);        \
  HAL_GPIO_WritePin(self.port, self.pin, state);          \
)
#define LED_WritePin(self, state)                         \
STATEMENT_(                                               \
  HAL_GPIO_WritePin(self.port, self.pin, state);          \
)
#define LED_TogglePin(self)                               \
STATEMENT_(                                               \
  HAL_GPIO_TogglePin(self.port, self.pin);                \
)

使用範例

你可以在主程式新增一個仿物件
LED led1;
然後對著他初始化,就是設定角位(下面是設置成 PC4)
LED_init(led1, GPIOG, GPIO_PIN_2, GPIO_PIN_RESET );
GPIO_PIN_RESET 起始狀態是0
GPIO_PIN_SET 起始狀態是1
然後我們點亮他吧
LED_TogglePin(led1);
嗯就這麼簡單,要加函式在自己加~應該很容易能看懂

2018年3月6日 星期二

Win10 如何使用 cmd指令 自動連接區網印表機

Win10 如何使用 cmd指令 自動連接區網印表機

找了好多資訊通通都錯了,大部分都是之前 xp 連接方式 win10 有一些指令不能用,最後終於被我翻到了。
話說 rundll32 printui.dll,PrintUIEntry 的說明怎麼這麼難懂 QuQ
下面是寫好的批次檔可直接用
@Echo Off
Title AddPath - By:Charlotte.HonG
:: Date :2017/11/29
:: Final :2018/03/06
::===========================================================
::確認是否為管理員權限
call :IsAdmin
::===========================================================
::設置資訊
set priIp="192.168.2.1"
set showName="Lab - dcp7040"
set infFullName="%~dp0BRPRMA7A.INF"
set infItem="Brother DCP-7040 Printer"

rem 印表機伺服器新增方法
:: 建立 ltp1 連接埠
set prnport="C:\Windows\System32\Printing_Admin_Scripts\zh-TW\prnport.vbs"
cscript %prnport% -a -r PortXX -h %priIp% -o raw -n 9100
:: 連接印表機並從inf安裝驅動
rundll32 printui.dll,PrintUIEntry /if /b%showName% /f%infFullName% /rPortXX /m%infItem%

rem 網路芳鄰分享的只能用這樣
:: 安裝裝驅動到 windows
rem pnputil -a %infFullName%
:: 呼叫新增網路印表機精靈
rem rundll32 printui.dll,PrintUIEntry /in /n\\%priIp%\dcp7040
::===========================================================
Exit

:IsAdmin
@Echo Off
Reg.exe query "HKU\S-1-5-19\Environment"
If Not %ERRORLEVEL% EQU 0 (
  Cls
  Echo [權限不足] 需使用管理員權限開啟
  Pause & Exit
)
goto:eof

參數說明

大致有以下幾個參數要改
set priIp=”192.168.2.1”
這個只是那台印表機的IP應該不是大問題,先確認手動連接可以連上就對了
set showName=”Lab - dcp7040”
這個是出現在電腦上的名稱,可自訂取一個好識別的
set infFullName=”%~dp0BRPRMA7A.INF”
這個要去驅動裡面挖,可以從”從磁碟片安裝”來測試哪一個,選對了就有東西可以安裝了
set infItem=”Brother DCP-7040 Printer”
上面從磁碟片安裝之後的選單看到的名稱就是了,也可以從 inf 裡面看到

指令說明

prnport

使用方法: prnport [-adlgt?] [-r port][-s server][-u user name][-w password]
[-o raw|lpr][-h host address][-q queue][-n number]
[-me | -md ][-i SNMP index][-y community][-2e | -2d]
引數:
-a - 新增連接埠
-d - 刪除指定的連接埠
-g - 取得 TCP 連接埠的組態設定
-h - 裝置的 IP 位址
-i - SNMP 索引,如果啟用了 SNMP
-l - 列出所有 TCP 連接埠
-m - SNMP 類型。[e] 啟用,[d] 停用
-n - 連接埠號碼,套用到 TCP RAW 連接埠
-o - 連接埠類型,raw 或 lpr
-q - 佇列名稱,只套用到 TCP LPR 連接埠
-r - 連接埠名稱
-s - 伺服器名稱
-t - 設定 TCP 連接埠的組態設定
-u - 使用者名稱
-w - 密碼
-y - 群體名稱,如果啟用了 SNMP
-2 - 雙重多工緩衝,套用到 TCP LPR 連接埠。[e] 表示啟用,[d] 表示停用
-? - 顯示命令使用方法
範例:
prnport -l -s server
prnport -d -s server -r IP_1.2.3.4
prnport -a -s server -r IP_1.2.3.4 -h 1.2.3.4 -o raw -n 9100
prnport -t -s server -r IP_1.2.3.4 -me -y public -i 1 -n 9100
prnport -g -s server -r IP_1.2.3.4
prnport -a -r IP_1.2.3.4 -h 1.2.3.4

rundll32 printui.dll,PrintUIEntry

使用方式: rundll32 printui.dll,PrintUIEntry [options] [@commandfile]
/a[file] 二進位檔案名稱
/b[name] 基本印表機名稱
/c[name] 如果動作發生在遠端電腦,則是電腦的 UNC 名稱
/dl 刪除本機印表機
/dn 刪除網路印表機連線
/dd 刪除印表機驅動程式
/e 顯示列印喜好設定
/f[file] 可以是 inf 檔案或輸出檔案
/F[file] INF 檔案的位置,以 /f 指定的 INF 檔案可能與其有相依關係
/ga 增加每台電腦的印表機連線 (使用者登入時,連線將傳播)
/ge 列舉每台電腦的印表機連線
/gd 刪除每台電腦的印表機連線 (使用者登入時,連線將刪除)
/h[arch] 下列其中一種驅動程式架構: x86、x64 或 Itanium
/ia 使用 inf 檔來安裝印表機驅動程式
/id 用新增印表機驅動程式精靈來新增印表機驅動程式
/if 使用 inf 檔來安裝印表機
/ii 啟動新增印表機精靈及 inf 檔來安裝印表機
/il 使用新增印表機精靈來安裝印表機
/im 使用新增印表機精靈安裝印表機,並跳過網路列出的印表機
/in 新增網路印表機連線
/ip 使用網路印表機安裝精靈安裝印表機
/j[provider] 列印提供者名稱
/k 列印測試頁到指定的印表機,安裝印表機時,不可和命令相結合
/l[path] 印表機驅動程式來源路徑
/m[model] 印表機驅動程式型號名稱
/n[name] 印表機名稱
/o 顯示印表機佇列檢視
/p 顯示印表機內容
/q 安靜模式,不顯示錯誤訊息
/r[port] 連接埠名稱
/s 顯示伺服器內容
/Ss 將印表機設定儲存到檔案
/Sr 從檔案還原印表機設定
儲存或還原必須放在命令結尾的印表機設定選項旗標:
2 PRINTER_INFO_2
7 PRINTER_INFO_7
c 色彩設定檔
d PrinterData
s 安全性描述元
g 全域 DevMode
m 最小設定
u 使用者 DevMode
r 解決名稱衝突
f 強制名稱
p 解析連接埠
i 驅動程式名稱衝突
/u 使用現有的印表機驅動程式 (若已安裝)
/t[#] 起始頁面 (以零為基礎的索引)
/v[version] 下列驅動程式版本之一,”類型 2 - 核心模式” 或 “類型 3 - 使用者模式”
/w 如果在 inf 檔內找不到指定的驅動程式,提示使用者提供驅動程式
/y 設定為預設的印表機
/Xg 取得印表機設定
/Xs 設定印表機設定
/z 不要自動共用此印表機
/Y 不要自動產生印表機名稱
/K 將 /h 代表的項目變更為接受 2、3、4 (分別為 x86、x64 或 Itanium),及 /v 代表的項目變更為接受 3 (“ 類型 3 - 使用者模式” )
/Z 共用此印表機,只能和 /if 選項配合使用
/? 說明此訊息
@[file] 命令列引數檔案
/Mw[message] 在認可命令之前先顯示警告訊息
/Mq[message] 在認可命令之前先顯示確認訊息
/W[flags] 指定精靈 (如 APW 和 APDW) 的旗標與切換參數
r 讓精靈可以從上一頁重新開始
/G[flags] 指定全域旗標與切換參數
w 抑制安裝驅動程式警告使用者介面出現 (極安靜模式)
/R 強制使用選取的驅動程式來取代現有的驅動程式

參考