target.h
来自「通过使机器人进行简单的图像识别」· C头文件 代码 · 共 279 行
H
279 行
/********************************************************************
*
* =-----------------------------------------------------------------=
* = ____ _________ =
* = / _ \ \___ __/ =
* = / /_/ / ____ / / =
* = / _ \ ● / _ \ / / =
* = / /_/ // // / / // / =
* = \______//_//_/ /_//_/ =
* = =
* = Copyright (c) BIN Technology studio,2004 =
* = LET'Z BT =
* =-----------------------------------------------------------------=
*
* FileName : Target.cpp Target.h
* Description : 查找目标(那个ex女人的手)
*
* Author : 风间苍月(TuQbasic)
* Email : tuqbasic@sohu.com
*
* Create : 2004.04.23
* LastChange : 2004.05.06
*
* History :
********************************************************************/
#pragma once
#include "ImageBuffer.h"
#include "Engine\hPackage.h"
typedef struct _sLineArea
{ // x轴与区域的交点
int iMin; // 最左端
int iMax; // 最右端
}LINEAREA;
typedef struct _tagFloatRect
{
float left;
float right;
float top;
float bottom;
}FLOATRECT;
typedef struct _sTargetArea
{
unsigned int iLineCountX; // 缓冲横向扫描线数,其实就是高度
LINEAREA *pLineX; // 横向扫描线
unsigned int iLineCountY; // 宽度
LINEAREA *pLineY; // 纵向扫描线
RECT maxRect; // 最大包含矩形
RECT rect; // 矩形区域,均值化之后
FLOATRECT delta; // 一次差绝对值,非线性度
double distance; // 大致距离,由位置和面积确定
_sTargetArea(void)
{
pLineX= NULL;
iLineCountX= 0;
pLineY= NULL;
iLineCountY= 0;
}
~_sTargetArea(void)
{
Free();
}
// 清除数据记录
void Clear(void)
{
for (int y= 0; y < iLineCountX; y++)
pLineX[y].iMin= pLineX[y].iMax= -1; // 标记为不可用
for (int x= 0; x < iLineCountY; x++)
pLineY[x].iMin= pLineY[x].iMax= -1;
maxRect.left= maxRect.right= maxRect.top= maxRect.bottom= 0;
rect.left= rect.right= rect.top= rect.bottom= 0;
delta.left= delta.right= delta.top= delta.bottom= 0.;
distance= 0.;
}
void ClearASM(void)
{
unsigned int icx= iLineCountX;
LINEAREA *plx= pLineX;
__asm
{
xor eax, eax;
mov ebx, icx;
mov edi, plx;
loop_y:
mov ecx, eax;
shl ecx, 3;
mov dword ptr [edi + ecx], -1;
mov dword ptr [edi + ecx + 4], -1;
inc eax;
cmp eax, ebx;
jb loop_y;
}
unsigned int icy= iLineCountY;
LINEAREA *ply= pLineY;
__asm
{
xor eax, eax;
mov ebx, icy;
mov edi, ply;
loop_x:
mov ecx, eax;
shl ecx, 3;
mov dword ptr [edi + ecx], -1;
mov dword ptr [edi + ecx + 4], -1;
inc eax;
cmp eax, ebx;
jb loop_x;
}
rect.left= rect.right= rect.top= rect.bottom= -1;
delta.left= delta.right= delta.top= delta.bottom= -1;
}
void Alloc(unsigned int wid, unsigned int hei)
{
iLineCountX= hei;
pLineX= new LINEAREA[hei];
iLineCountY= wid;
pLineY= new LINEAREA[wid];
}
void Free(void)
{
iLineCountX= 0;
if (pLineX)
{
delete[] pLineX;
pLineX= NULL;
}
iLineCountY= 0;
if (pLineY)
{
delete[] pLineY;
pLineY= NULL;
}
}
}TARGETAREA;
typedef struct _sRatioParam
{
// 最小长宽
int MinWidth;
int MinHeight;
// 纵横比
float MinHW;
float MaxHW;
// 非线性度
FLOATRECT antiLineNear;
FLOATRECT antiLineFar;
// 丢失时间
int LostTime;
// 判断近处的条件
int NearS;
int NearTop;
int NearBottom;
}RATIOPARAM;
class CTarget
{
public:
CTarget(void);
~CTarget(void);
//
void LoadRatioParam(LPI_FILEINI pIni)
{
m_ratio.MinHW= pIni->getKeyValueDouble("RatioMinHW", "Target");
m_ratio.MaxHW= pIni->getKeyValueDouble("RatioMaxHW", "Target");
m_ratio.antiLineNear.top= pIni->getKeyValueDouble("RatioTop", "TargetNear");
m_ratio.antiLineNear.bottom=pIni->getKeyValueDouble("RatioBottom", "TargetNear");
m_ratio.antiLineNear.left= pIni->getKeyValueDouble("RatioLeft", "TargetNear");
m_ratio.antiLineNear.right= pIni->getKeyValueDouble("RatioRight", "TargetNear");
m_ratio.antiLineFar.top= pIni->getKeyValueDouble("RatioTop", "TargetFar");
m_ratio.antiLineFar.bottom= pIni->getKeyValueDouble("RatioBottom", "TargetFar");
m_ratio.antiLineFar.left= pIni->getKeyValueDouble("RatioLeft", "TargetFar");
m_ratio.antiLineFar.right= pIni->getKeyValueDouble("RatioRight", "TargetFar");
m_ratio.MinWidth= pIni->getKeyValueLong("RatioMinWidth", "Target");
m_ratio.MinHeight= pIni->getKeyValueLong("RatioMinHeight", "Target");
m_ratio.LostTime= pIni->getKeyValueLong("LostTime", "Target");
m_ratio.NearS= pIni->getKeyValueLong("NearS", "Target");
m_ratio.NearTop= pIni->getKeyValueLong("NearTop", "Target");
m_ratio.NearBottom= pIni->getKeyValueLong("NearBottom", "Target");
}
// 分配所需的内存空间
bool Alloc(unsigned int wid, unsigned int hei);
// 释放内存
void Free(void);
// 查找目标
bool UpdateTarget(CImageBuffer<unsigned char> *pSrc);
// 绘制区域轮廓
void DrawTargetBorder(CImageBuffer<unsigned char> *pDst);
void DrawTargetBorderASM(CImageBuffer<unsigned char> *pDst);
// 绘制区域
void DrawTargetArea(CImageBuffer<unsigned char> *pDst);
void DrawTargetAreaASM(CImageBuffer<unsigned char> *pDst);
void DrawTargetRect(CImageBuffer<unsigned char> *pDst);
// 是否失去方向(丢失目标一定时间)
bool IsLost(void)
{
return ((GetTickCount() - m_lLostTime) > m_ratio.LostTime) ? true : false;
}
//
void GetTarget(RECT &r) { r= m_pPreTarget->rect;}
protected:
// 擦除标记的区域
void ClearArea(CImageBuffer<unsigned char> *pSrc, TARGETAREA *pTarget);
void ClearAreaASM(CImageBuffer<unsigned char> *pSrc, TARGETAREA *pTarget);
// 搜寻轮廓并整理记录遍历的点
void TraceBorder(int x, int y, CImageBuffer<unsigned char> *pSrc, TARGETAREA *pTarget);
void TraceBorderASM(int x, int y, CImageBuffer<unsigned char> *pSrc, TARGETAREA *pTarget);
// 去除上部10%
void ClearTop(TARGETAREA *pTarget);
// 计算目标的参数,边界的均值及与均值的差累计
void TraceBlock(TARGETAREA *pTarget);
void TraceBlockEx(TARGETAREA *pTarget);
// 计算非线性度
void TraceLine(TARGETAREA *pTarget, int xpt, int ypt, int top, int bottom, int left, int right); // 按与均值的差
void TraceLineEx(TARGETAREA *pTarget, int xpt, int ypt); // 每点的delta值
// 测试距离
void TestDistance(TARGETAREA *pTarget);
// 初步判断是否为目标
bool IsTarget(TARGETAREA *pTarget);
// 比较两个查找出来的疑似目标,更新最优目标
void CompareBestBlock(void);
// 当有疑似目标在左右边缘时用该函数比较
void CompareBestBlockEx(void);
// 判断一个矩形是否可能在视野边界上
bool IsOutView(RECT &rect);
private:
TARGETAREA *m_pPreTarget; // 已有对象,存放最优解
TARGETAREA *m_pTarget; // 新查找出的目标
RATIOPARAM m_ratio; // 目标阈值
long m_lLostTime; // 最后一次获取目标的时间
};
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?