读了一篇论文,没事仿真一下,国产的论文真心难,不过有些思想还是可以借鉴的。下面主要说一下论文中的两个对多云和小目标的特性的分析:
1、八邻域局部特征对比标准差
这里只利用了标准差
2、八方向剖线长度标准差
void regionDeleteSec(structTargetParam_vector &TargetParam)
{
structTargetParam_vector TargetParamSec = TargetParam;
if (TargetParamSec.len > 0)
{
int new_len = 0;
//计算疑似目标所在区域的灰度均值
std::vector<float> SVec;
std::vector<float> lenValVec;
for (int i = 0; i < TargetParamSec.len; i++)
{
float grayMeanVal0 = 0; float grayMeanVal1 = 0; float grayMeanVal2 = 0; float grayMeanVal3 = 0;
float grayMeanVal4 = 0; float grayMeanVal5 = 0; float grayMeanVal6 = 0; float grayMeanVal7 = 0; float grayMeanVal8 = 0;
int countFlag = 0;
//top比bottom要小
if (TargetParamSec.data[i].x_left - TargetParamSec.data[i].x_length >= 0
&& TargetParamSec.data[i].x_right + TargetParamSec.data[i].x_length < frame.cols
&& TargetParamSec.data[i].y_top - TargetParamSec.data[i].y_length >= 0
&& TargetParamSec.data[i].y_bottom + TargetParamSec.data[i].y_length < frame.rows)
{
//中间为8,左上开始以此为0-7
grayMeanVal8 = calGrayMeanVal(frame, TargetParamSec.data[i].x_left, TargetParamSec.data[i].y_top,
TargetParamSec.data[i].x_length, TargetParamSec.data[i].y_length);
//- -
grayMeanVal0 = calGrayMeanVal(frame, TargetParamSec.data[i].x_left - TargetParamSec.data[i].x_length,
TargetParamSec.data[i].y_top - TargetParamSec.data[i].y_length,
TargetParamSec.data[i].x_length, TargetParamSec.data[i].y_length);
//= -
grayMeanVal1 = calGrayMeanVal(frame, TargetParamSec.data[i].x_left,
TargetParamSec.data[i].y_top - TargetParamSec.data[i].y_length,
TargetParamSec.data[i].x_length, TargetParamSec.data[i].y_length);
//+ -
grayMeanVal2 = calGrayMeanVal(frame, TargetParamSec.data[i].x_left + TargetParamSec.data[i].x_length,
TargetParamSec.data[i].y_top - TargetParamSec.data[i].y_length,
TargetParamSec.data[i].x_length, TargetParamSec.data[i].y_length);
//+ =
grayMeanVal3 = calGrayMeanVal(frame, TargetParamSec.data[i].x_left + TargetParamSec.data[i].x_length,
TargetParamSec.data[i].y_top,
TargetParamSec.data[i].x_length, TargetParamSec.data[i].y_length);
//+ +
grayMeanVal4 = calGrayMeanVal(frame, TargetParamSec.data[i].x_left + TargetParamSec.data[i].x_length,
TargetParamSec.data[i].y_top + TargetParamSec.data[i].y_length,
TargetParamSec.data[i].x_length, TargetParamSec.data[i].y_length);
//= +
grayMeanVal5 = calGrayMeanVal(frame, TargetParamSec.data[i].x_left,
TargetParamSec.data[i].y_top + TargetParamSec.data[i].y_length,
TargetParamSec.data[i].x_length, TargetParamSec.data[i].y_length);
//- +
grayMeanVal6 = calGrayMeanVal(frame, TargetParamSec.data[i].x_left - TargetParamSec.data[i].x_length,
TargetParamSec.data[i].y_top + TargetParamSec.data[i].y_length,
TargetParamSec.data[i].x_length, TargetParamSec.data[i].y_length);
//- =
grayMeanVal7 = calGrayMeanVal(frame, TargetParamSec.data[i].x_left - TargetParamSec.data[i].x_length,
TargetParamSec.data[i].y_top,
TargetParamSec.data[i].x_length, TargetParamSec.data[i].y_length);
float M = (abs(grayMeanVal8 - grayMeanVal0) + abs(grayMeanVal8 - grayMeanVal0) +
abs(grayMeanVal8 - grayMeanVal1) + abs(grayMeanVal8 - grayMeanVal2) +
abs(grayMeanVal8 - grayMeanVal3) + abs(grayMeanVal8 - grayMeanVal4) +
abs(grayMeanVal8 - grayMeanVal5) + abs(grayMeanVal8 - grayMeanVal6) +
abs(grayMeanVal8 - grayMeanVal5) + abs(grayMeanVal8 - grayMeanVal6)) / 8;
float S = std::sqrt((std::pow((abs(grayMeanVal8 - grayMeanVal0) - M), 2) + std::pow((abs(grayMeanVal8 - grayMeanVal1) - M), 2)
+ std::pow((abs(grayMeanVal8 - grayMeanVal2) - M), 2) + std::pow((abs(grayMeanVal8 - grayMeanVal3) - M), 2)
+ std::pow((abs(grayMeanVal8 - grayMeanVal4) - M), 2) + std::pow((abs(grayMeanVal8 - grayMeanVal5) - M), 2)
+ std::pow((abs(grayMeanVal8 - grayMeanVal6) - M), 2) + std::pow((abs(grayMeanVal8 - grayMeanVal7) - M), 2))) / 8;
//计算返回的长度标准差
if (TargetParamSec.data[i].x_center - 40 > 0
&& TargetParamSec.data[i].x_center + 40 < frame.cols
&&TargetParamSec.data[i].y_center - 15 > 0
&& TargetParamSec.data[i].y_center + 15 < frame.rows)
{
float lenVal = calLineLen(frame01, TargetParamSec.data[i].x_center, TargetParamSec.data[i].y_center, 80, 30);
SVec.push_back(S);
lenValVec.push_back(lenVal);
}
}
}
//
//归一化后,每一组参数分配一个权重,进行约束
float w1 = 0.1; float w2 = 0.9; /*float w3 = 0.2;*/
float SRes = 0.0; float lenRes = 0.0; float countRes = 0.0;
for (int i = 0; i < SVec.size(); i++)
{
SRes += SVec[i];
lenRes += lenValVec[i];
}
if (SVec.size() > 1)
{
for (int i = 0; i < SVec.size(); i++)
{
float SWeights = 1/(SVec[i] / SRes);//灰度的标准差越大越好,求导后越小越好
float lenWeights = lenValVec[i] / lenRes;//长度标准差越小越好
float normalVal = (w1 * SWeights + w2 * lenWeights) / (sqrt(pow(SWeights, 2) + pow(lenWeights, 2)));
TargetParamSec.data[i].normalVal = normalVal;
}
for (int i = 0; i <= TargetParamSec.len - 1; i++) {
for (int j = i + 1; j < TargetParamSec.len; j++) {
structTargetParam temp;
if (TargetParamSec.data[j].normalVal < TargetParamSec.data[i].normalVal) {
temp = TargetParamSec.data[j];
TargetParamSec.data[j] = TargetParamSec.data[i];
TargetParamSec.data[i] = temp;
}
}
}
}
else if (SVec.size() == 1)
{
TargetParam = TargetParamSec;
new_len = 1;
}
else
{
;
}
}
}
//计算8个方向剖线长度
float calLineLen(cv::Mat frame, int center_x, int center_y, int width, int height)
{
int len0 = 0; int len1 = 0; int len2 = 0; int len3 = 0; int len4 = 0; int len5 = 0; int len6 = 0; int len7 = 0;
float lenVal = 0.0;
//左上
for (int i = center_y,j=center_x; i < center_y - height / 2,j < center_x - width/2; i--,j--)
{
if ((int)frame.ptr<char>(i)[j] > 0)
{
len0++;
}
//else
//{
// break;
//}
}
//正上
for (int i = center_y; i < center_y - height / 2; i--)
{
if ((int)frame.ptr<char>(i)[center_x] > 0)
{
len1++;
}
//else
//{
// break;
//}
}
//右上
for (int i = center_y, j = center_x; i < center_y - height / 2, j < center_x + width / 2; i--,j++)
{
if ((int)frame.ptr<char>(i)[j] > 0)
{
len2++;
}
//else
//{
// break;
//}
}
//右
for (int j = center_x; j < center_x + width / 2; j++)
{
if ((int)frame.ptr<char>(center_y)[j] > 0)
{
len3++;
}
//else
//{
// break;
//}
}
//右下
for (int i = center_y, j = center_x; i < center_y + height / 2, j < center_x + width / 2; i++, j++)
{
if ((int)frame.ptr<char>(i)[j] > 0)
{
len4++;
}
//else
//{
// break;
//}
}
//正下
for (int i = center_y; i < center_y + height / 2; i++)
{
if ((int)frame.ptr<char>(i)[center_x] > 0)
{
len5++;
}
//else
//{
// break;
//}
}
//左下
for (int i = center_y, j = center_x; i < center_y + height / 2, j < center_x - width / 2; i++, j--)
{
if ((int)frame.ptr<char>(i)[j] > 0)
{
len6++;
}
//else
//{
// break;
//}
}
//左
for (int j = center_x; j < center_x - width / 2; j--)
{
if ((int)frame.ptr<char>(center_y)[j] > 0)
{
len7++;
}
//else
//{
// break;
//}
}
//计算标准差
float lu = (float)(len0 + len1 + len2 + len3 + len4 + len5 + len6 + len7) / 8.0;
lenVal = sqrt(pow(lu - (float)len0, 2) + pow(lu - (float)len1, 2) + pow(lu - (float)len2, 2) +
pow(lu - (float)len3, 2) + pow(lu - (float)len4, 2) + pow(lu - (float)len5, 2) +
pow(lu - (float)len6, 2) + pow(lu - (float)len7, 2)) / 8.0;
return lenVal;
}
//计算区域的灰度均值
float calGrayMeanVal(cv::Mat frame, int leftVal, int topVal, int width, int height)
{
int grayTotalVal = 0;
float grayMeanVal = 0.0;
for (int i = topVal; i < topVal + height; i++)
{
for (int j = leftVal; j < leftVal + width ; j++)
{
grayTotalVal += (int)frame.ptr<char>(i)[j];
}
}
grayMeanVal = (float)grayTotalVal / (width*height);
return grayMeanVal;
}
权重这一块可以按照论文的方式用SVM学习得到,或者设计一个网络来学习。