檢測faster-rcnn或者yolo目標檢測演算法後的bbox中物體的大概角度。
1.首先將原圖分為bgr三個通道,將其中兩個通道加權求和之後進行灰度化,我這裡採用的是4g-1b,如果下一步驟的閾值分割效果不好,可以嘗試一下其他兩個通道加權求和。
mat mv[3]
;split
(src,mv)
;mat img;
addweighted
(mv[1]
,4,mv[0]
,-1,
0,img)
;
2.使用閾值分割,這裡推薦otsu閾值分割和迭代閾值分割,這兩種的效果最好,**如下
mat gray;
gray=
iterationthreshold
(img)
;
//otsu閾值分割
mat otsualgthreshold
(mat &image)
int t =0;
//otsu演算法閾值
double varvalue =0;
//類間方差中間值儲存
double w0 =0;
//前景畫素點數所佔比例
double w1 =0;
//背景畫素點數所佔比例
double u0 =0;
//前景平均灰度
double u1 =0;
//背景平均灰度
double histogram[
256]=;
//灰度直方圖,下標是灰度值,儲存內容是灰度值對應的畫素點總數
uchar *data = image.data;
double totalnum = image.rows*image.cols;
//畫素總數
for(
int i =
0; i < image.rows; i++)}
int minpos, maxpos;
for(
int i =
0; i <
255; i++)}
for(
int i =
255; i >
0; i--)}
for(
int i = minpos; i <= maxpos; i++)if
(w1 ==0)
//背景部分畫素點數為0時退出
u1 = u1 / w1;
//背景畫素平均灰度
w1 = w1 / totalnum;
// 背景部分畫素點數所佔比例
//***********背景各分量值計算**************************
//***********前景各分量值計算**************************
for(
int k = i +
1; k <
255; k++)if
(w0 ==0)
//前景部分畫素點數為0時退出
u0 = u0 / w0;
//前景畫素平均灰度
w0 = w0 / totalnum;
// 前景部分畫素點數所佔比例
//***********前景各分量值計算**************************
//***********類間方差計算******************************
double varvaluei = w0*w1*
(u1 - u0)
*(u1 - u0)
;//當前類間方差計算
if(varvalue < varvaluei)
} mat dst;
threshold
(image, dst, t,
255, cv_thresh_otsu)
;return dst;
}
//迭代閾值分割
mat iterationthreshold
(mat src)
;for
(int j =
0; j < height; j++
)int t0 =0;
for(
int i =
0; i <
256; i++
) t0 /
= width*height;
int t1 =
0, t2 =0;
int num1 =
0, num2 =0;
int t =0;
while(1
)if(num1 ==0)
continue
;for
(int i = t0 +
1; i <
256; i++)if
(num2 ==0)
continue
; t =
(t1 / num1 + t2 / num2)/2
;if(t == t0)
break
;else
t0 = t;
} mat dst;
threshold
(src, dst, t,
255,0)
;return dst;
}
3.膨脹處理
mat morphologydst;
cv::
morphologyex
(gray, morphologydst, cv::morph_dilate,
cv::
getstructuringelement
(cv::morph_rect, cv::
size(7
,1))
);
4.找出最小外接矩形,由於進行膨脹處理後,圖中還有一些黑點,沒有用孔洞填充,直接用乙個最笨的方法,由於圖中只有乙個物體,因此,可以遍歷其中所有的最小外接矩形,選出最大的乙個,就是要找的那個,也嘗試一下孔洞填充,但是感覺效果不咋地,孔洞填充**如下,需要的可以嘗試一下。
vector> contours;
vector hierarchy;
findcontours
point(0
,0))
;vector
minrect
(contours.
size()
);float area=0;
for(
int i =
0; i < contours.
size()
; i++
)
//孔洞填充
void
fillhole
(const mat srcbw, mat &dstbw)
5.將外接矩形框畫出,這裡有個比較重要的是,opencv提供的rotatedrect中的角度是相對角度,(-90,0],需要將其轉換為絕對角度。
mat drawing=src;
for(
int i =
0; i< contours.
size()
; i++
)}
//將相對角度轉化為絕對角度
static
double
calclinedegree
(const point2f& firstpt,
const point2f& secondpt)
}else
return curlineangle*
180.0f
/cv_pi;
}static
double
getrcdegree
(const rotatedrect box)
else
return degree;
}
檢測效果:
判斷乙個遊戲物體在另乙個遊戲物體的左邊或者右邊
最近在公司專案裡面做乙個boss戰鬥,boss有兩個轉向動畫,乙個向左轉,乙個向右轉,轉向之前你首先需要判斷人物位置當前在boss的左邊還是右邊,可以使用 float result vector3.cross boss.transform.forward,人物到boss的向量 y 如果結果是正,則表...
MySQL 乙個簡單insert語句的大概流程
mysql create table testin id int query ok,0 rows affected 2.38 sec mysql insert into testin values 10 query ok,1 row affected 0.02 sec 126 t 2 thd ent...
登陸的乙個大概流程
登陸的乙個大概流程 1 接受登陸引數 2 引數的合法性檢驗 3 檢驗成功,執行使用者名稱是否存在的查詢 4 如果不存在該使用者,返回登陸頁面,並加入提示資訊 5 如果存在,檢驗密碼是否正確,如果密碼不正確,返回登陸頁面,加入提示資訊 6 密碼匹配正確的情況下,user使用者加入session,執行跳...