opencv求解區(qū)域的內(nèi)接矩形
實(shí)驗(yàn)室項(xiàng)目中,希望求取一個(gè)近似圓形區(qū)域的質(zhì)心,原本使用最小外接圓的質(zhì)心來等效為該區(qū)域質(zhì)心。但是由于部分區(qū)域的形狀過于不規(guī)則導(dǎo)致發(fā)生質(zhì)心偏移現(xiàn)象。如下圖:
藍(lán)色為實(shí)際要求質(zhì)心。紅色為等效圓質(zhì)心
為獲取較為準(zhǔn)確的質(zhì)心,擬用最大內(nèi)接矩形的中心作為該區(qū)域質(zhì)心。
采用改進(jìn)的中心擴(kuò)散法求內(nèi)接矩形:先以最小外接矩的中心作為算法的起點(diǎn)進(jìn)行中心擴(kuò)散。得到一個(gè)內(nèi)解矩形,在對最小外接矩的中心進(jìn)行8鄰域的遍歷,應(yīng)用中心擴(kuò)散法分別求取內(nèi)接矩,以面積最大的內(nèi)接矩作為最大內(nèi)接矩。
使用Opencv關(guān)鍵代碼如下:
/** * @brief 求取連通區(qū)域內(nèi)接矩 * @param img:輸入圖像,單通道二值圖,深度為8 * @param center:最小外接矩的中心 * @return 最大內(nèi)接矩形 * 基于中心擴(kuò)展算法 */ cv::Rect InSquare(Mat &img,const Point center) { // --[1]參數(shù)檢測 if(img.empty()|| img.channels()>1 ||img.depth()>8) return Rect(); //[1] // --[2] 初始化變量 int edge[4]; edge[0]=center.y+1;//top edge[1]=center.x+1;//right edge[2]=center.y-1;//bottom edge[3]=center.x-1;//left //[2] // --[3]邊界擴(kuò)展(中心擴(kuò)散法) bool EXPAND[4]={1,1,1,1};//擴(kuò)展標(biāo)記位 int n=0; while (EXPAND[0]||EXPAND[1]||EXPAND[2]||EXPAND[3]) { int edgeID=n%4; EXPAND[edgeID]=expandEdge(img,edge,edgeID); n++; } //[3] qDebug()<<edge[0]<<edge[1]<<edge[2]<<edge[3]; Point tl=Point(edge[3],edge[0]); Point br=Point(edge[1],edge[2]); return Rect(tl,br); } /** * @brief expandEdge 擴(kuò)展邊界函數(shù) * @param img:輸入圖像,單通道二值圖,深度為8 * @param edge 邊界數(shù)組,存放4條邊界值 * @param edgeID 當(dāng)前邊界號 * @return 布爾值 確定當(dāng)前邊界是否可以擴(kuò)展 */ bool expandEdge(const Mat & img, int edge[], const int edgeID) { //[1] --初始化參數(shù) int nc=img.cols; int nr=img.rows; switch (edgeID) { case 0: if(edge[0]>nr) return false; for(int i=edge[3];i<=edge[1];++i) { if(img.at<uchar>(edge[0],i)==0) return false; } edge[0]++; return true; break; case 1: if(edge[1]>nc) return false; for(int i=edge[2];i<=edge[0];++i) { if(img.at<uchar>(i,edge[1])==0) return false; } edge[1]++; return true; break; case 2: if(edge[2]<0) return false; for(int i=edge[3];i<=edge[1];++i) { if(img.at<uchar>(edge[2],i)==0) return false; } edge[2]--; return true; break; case 3: if(edge[3]<0) return false; for(int i=edge[2];i<=edge[0];++i) { if(img.at<uchar>(i,edge[3])==0) return false; } edge[3]--; return true; break; default: return false; break; } }
效果:
黑色為內(nèi)接矩中心,紅色為最小外接圓中心
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
詳解C++內(nèi)存的代碼區(qū),全局區(qū),棧區(qū)和堆區(qū)
這篇文章主要為大家介紹了C++內(nèi)存的代碼區(qū),全局區(qū),棧區(qū)和堆區(qū),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2021-12-12C++開發(fā)之PugiXML庫基礎(chǔ)用法示例詳解
PugiXML庫是一個(gè)功能強(qiáng)大、簡單易用的C++ XML解析庫,它提供了一組方便的函數(shù)來解析、創(chuàng)建和修改XML文檔,本文介紹了如何使用PugiXML庫來解析、創(chuàng)建和修改XML文檔,以及如何處理錯(cuò)誤和異常,感興趣的朋友跟隨小編一起看看吧2024-03-03C語言實(shí)現(xiàn)數(shù)據(jù)結(jié)構(gòu)迷宮實(shí)驗(yàn)
這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)數(shù)據(jù)結(jié)構(gòu)迷宮實(shí)驗(yàn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-03-03C++ OpenCV實(shí)戰(zhàn)之圖像全景拼接
本文主要介紹了如何使用OpenCV C++ 進(jìn)行圖像全景拼接,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)OpenCV有一定的幫助,感興趣的可以了解一下2022-01-01