参考论文《基于移动式管道滤波的红外小目标检测方法研究》
仿真代码如下:
//判断一点的位置在邻域内
bool pointInterNeibor(cv::Point2f pointPos, cv::Point2f curX,int n,int width,int height)
{
cv::Rect2f neiborRoi;
int bordenLeft = 0;
int bordenRight = 0;
int bordenTop = 0;
int bordenBottom = 0;
bordenLeft = curX.x - n < 0 ? 0 : curX.x - n;
bordenRight= curX.x + n > width ? width : curX.x + n;
bordenLeft = curX.x - n < 0 ? 0 : curX.x - n;
bordenTop = curX.y - n < 0 ? 0 : curX.y - n;
bordenBottom = curX.y + n > height ? height : curX.y + n;
bool res = false;
if ((pointPos.x > bordenLeft)&& (pointPos.x<bordenRight)&&
(pointPos.y>bordenTop) && (pointPos.y < bordenBottom))
{
res = true;
}
else
{
res = false;
}
return res;
}
//5帧图像目标的数组,取第一帧作为当前帧,在下一帧观察其小邻域内是否有目标存在,有,则目标计数器加1
//同时比较目标点和可疑目标点的位置,如果有变化,则相应的目标变化计数器加1,记录该帧的目标位置,并将
//其设为候选目标点的当前位置
cv::Point2f guandaoFilter(queue<vector<cv::Point2f>> targetPosQ)
{
vector<cv::Point2f> singleTargetPos, copySingleTargetPos;
vector<cv::Point2f>secTargetPos;
vector<cv::Point2f>thirdTargetPos;
vector<cv::Point2f>fourTargetPos;
vector<cv::Point2f>fiveTargetPos;
cv::Point2f currentPos;
vector<int>targetFlagVec;
vector<int>targetPosFlagVec;
singleTargetPos = targetPosQ.front();
copySingleTargetPos = targetPosQ.front();
targetPosQ.pop();
for (int i = 0; i < singleTargetPos.size(); i++)
{
queue<vector<cv::Point2f>>tempPosQ;
int targetFlag = 0;
int targetPosFlag = 0;
tempPosQ = targetPosQ;
secTargetPos = tempPosQ.front();
for (int j = 0; j < secTargetPos.size(); j++)
{
if (pointInterNeibor(secTargetPos[j], singleTargetPos[i], 1, 640, 512))
{
targetFlag++;
if ((secTargetPos[j].x != singleTargetPos[i].x) || (secTargetPos[j].y != singleTargetPos[i].y))
{
singleTargetPos[i].x = secTargetPos[j].x;
singleTargetPos[i].y = secTargetPos[j].y;
targetPosFlag++;
}
else
{
;
}
}
}
tempPosQ.pop();
thirdTargetPos = tempPosQ.front();
for (int j = 0; j < thirdTargetPos.size(); j++)
{
if (pointInterNeibor(thirdTargetPos[j], singleTargetPos[i], 1, 640, 512))
{
targetFlag++;
if ((thirdTargetPos[j].x != singleTargetPos[i].x) || (thirdTargetPos[j].y != singleTargetPos[i].y))
{
singleTargetPos[i].x = thirdTargetPos[j].x;
singleTargetPos[i].y = thirdTargetPos[j].y;
targetPosFlag++;
}
else
{
;
}
}
}
tempPosQ.pop();
fourTargetPos = tempPosQ.front();
for (int j = 0; j < fourTargetPos.size(); j++)
{
if (pointInterNeibor(fourTargetPos[j], singleTargetPos[i], 1, 640, 512))
{
targetFlag++;
if ((fourTargetPos[j].x != singleTargetPos[i].x) || (fourTargetPos[j].y != singleTargetPos[i].y))
{
singleTargetPos[i].x = fourTargetPos[j].x;
singleTargetPos[i].y = fourTargetPos[j].y;
targetPosFlag++;
}
else
{
;
}
}
}
tempPosQ.pop();
fiveTargetPos = tempPosQ.front();
for (int j = 0; j < fiveTargetPos.size(); j++)
{
if (pointInterNeibor(fiveTargetPos[j], singleTargetPos[i], 1, 640, 512))
{
targetFlag++;
if ((fiveTargetPos[j].x != singleTargetPos[i].x) || (fiveTargetPos[j].y != singleTargetPos[i].y))
{
singleTargetPos[i].x = fiveTargetPos[j].x;
singleTargetPos[i].y = fiveTargetPos[j].y;
targetPosFlag++;
}
else
{
;
}
}
}
tempPosQ.pop();
targetFlagVec.push_back(targetFlag);
targetPosFlagVec.push_back(targetPosFlag);
}
for (int i = 0; i < targetFlagVec.size(); i++)
{
if (targetFlagVec[i] > 3 && targetPosFlagVec[i]>2)
{
currentPos = copySingleTargetPos[i]; //返回的是比较的第一帧的点的坐标
}
}
return currentPos;
}
试验发现对于运动目标效果还行,但是无法解决静止目标,需要配合其他算法。