opencv實現簡單手指位置識別

2021-08-02 19:08:38 字數 3312 閱讀 3776

整體思路:

1.過濾雜訊

2.由於rgb顏色的離散性轉換為hsv通道

3.對hsv空間進行量化,得到2值影象,亮的部分為手的形狀

4.去除雜點造成的偽輪廓,留下手的真實輪廓

5.對凸出點連線

6.最高點到底部中點的連線即為手指方向

//部分**:

將mfc實現部分給省略了,給出了完整的opencv部分**,可以參考實現。

int main()

//cv::mat frame;

cv::mat framehsv;

//std::vector

< std::vector

> originalcontours;//輪廓

std::vector

< cv::vec4i > hierarchy; // 輪廓的結構資訊

//std::vector

< std::vector

> finalcontours;// 篩選後的輪廓

std::vector

< cv::point > hull; // 凸包絡的點集

// cstring str;

int i, j;

int width = cap.get(cv_cap_prop_frame_width), height = cap.get(cv_cap_prop_frame_height);

float fheight = ((float)2 / 3 - (float)1 / 7) * height;

//while (0 == pdlg->m_bstopflag)

//左右翻轉

cv::flip(frame, frame, 1);

//中值濾波,用了這個下面的其他濾波全部異常

//medianblur(frame, frame, 10);

//高斯濾波

cv::gaussianblur(frame, frame, cv::size(7, 7), 1.5, 1.5);

//通道轉換

cv::cvtcolor(frame, framehsv, cv_bgr2hsv);

//imshow("framehsv", framehsv);

/* s = 符號整型 u = 無符號整型 f = 浮點型

e.g.:

cv_8uc1 是指乙個8位無符號整型單通道矩陣,

cv_32fc2是指乙個32位浮點型雙通道矩陣

cv_8uc1 cv_8sc1 cv_16u c1 cv_16sc1

cv_8uc2 cv_8sc2 cv_16uc2 cv_16sc2

cv_8uc3 cv_8sc3 cv_16uc3 cv_16sc3

cv_8uc4 cv_8sc4 cv_16uc4 cv_16sc4

cv_32sc1 cv_32fc1 cv_64fc1

cv_32sc2 cv_32fc2 cv_64fc2

cv_32sc3 cv_32fc3 cv_64fc3

cv_32sc4 cv_32fc4 cv_64fc4

*/// 對hsv空間進行量化,得到2值影象,亮的部分為手的形狀

cv::mat mask(frame.rows, frame.cols, cv_8uc1);

//inrange(framehsv, cv::scalar(0, 30, 30), cv::scalar(40, 170, 256), mask);

inrange(framehsv, cv::scalar(5, 30, 30), cv::scalar(40, 170, 256), mask);

//// 腐蝕:去除小亮點 膨脹:連線區塊

cv::erode(mask, mask, cv::mat(5, 5, cv_8u), cv::point(-1, -1), 1);

//cv::dilate(mask, mask, cv::mat(5, 5, cv_8u), cv::point(-1, -1), 2);

//imshow("framehsv", framehsv);

//imshow("mask", mask);

originalcontours.clear();

hierarchy.clear();

finalcontours.clear();

// 得到手的輪廓

// 去除偽輪廓

for (i = 0; i < originalcontours.size(); i++)

}// 畫輪廓

cv::drawcontours(frame, finalcontours, -1, cv::scalar(0, 0, 255), 3);

// 得到輪廓的凸包絡

int hullcount;

int inumofcontours = finalcontours.size();

cv::point top;

for (j = 0; j < inumofcontours; j++)

cv::line(frame, hull[hullcount - 1], hull[0], cv::scalar(255, 0, 0), 2, cv_aa);

//畫點

gettoppoint(hull, hullcount, top);

cv::line(frame, top, top, cv::scalar(255, 0, 255), 18, cv_aa);

cv::line(frame, top, cv::point(width/2, height), cv::scalar(0, 255, 255), 2, cv_aa);

//if (1 == inumofcontours)}//

cv::line(frame, cv::point(0, height / 7), cv::point(width, height / 7), cv::scalar(255, 255, 255), 2, cv_aa);

cv::line(frame, cv::point(0, 2 * height / 3), cv::point(width, 2 * height / 3), cv::scalar(255, 255, 255), 2, cv_aa);

imshow("frame", frame);

cv::waitkey(33);

}return

0;}

實驗效果圖

實現移動端單手指拖動 雙手指拉大放小

最近開發乙個專案中,有乙個模組是可以輕鬆檢視房屋的圖紙,實現單手指拖動平移,雙手指外拉放大,內拉縮小的這麼個功能,我比較懶,乾脆就不自己敲 有乙個外掛程式,它的名字叫easytouch,這個外掛程式把 都已經寫號了,下面我介紹一下如何使用 很簡單,總結起來三步 1.建立乙個plane,這個plane...

OpenCV實現簡單案例

折騰了兩天的opencv,終於在clion上配置好了opencv,並能夠正常使用!所以跑了一些簡單的 1,簡單例項 include include include 核心模組 include gui使用者介面 include 影象處理 using namespace cv using namespac...

opencv 簡單的實現HoughLinesP

兩點之間的距離 double juli int x1,int y1,int x2,int y2 輸入經過霍夫變換得到的直線 儲存起點和終點的vector 直線最短距離 點之間間隔最長距離 void houghlinesp mat img,vector lines,vector points,doub...