📄 dlgpatternrecog.cpp
字号:
switch (m_nWhichColorNoUse)
{
case COLOR_RED:
sumx=sumx+m_arrAutoSampleObjData[i].G;
sumy=sumy+m_arrAutoSampleObjData[i].B;
break;
case COLOR_GREEN:
sumx=sumx+m_arrAutoSampleObjData[i].R;
sumy=sumy+m_arrAutoSampleObjData[i].B;
break;
case COLOR_BLUE:
sumx=sumx+m_arrAutoSampleObjData[i].R;
sumy=sumy+m_arrAutoSampleObjData[i].G;
}
}
btBestObjXMean=sumx/m_arrAutoSampleObjData.GetSize();
btBestObjYMean=sumy/m_arrAutoSampleObjData.GetSize();
sumx=sumy=0;
for(i=0;i<m_arrAutoSampleBakData.GetSize();i++)
{
switch (m_nWhichColorNoUse)
{
case COLOR_RED:
sumx=sumx+m_arrAutoSampleBakData[i].G;
sumy=sumy+m_arrAutoSampleBakData[i].B;
break;
case COLOR_GREEN:
sumx=sumx+m_arrAutoSampleBakData[i].R;
sumy=sumy+m_arrAutoSampleBakData[i].B;
break;
case COLOR_BLUE:
sumx=sumx+m_arrAutoSampleBakData[i].R;
sumy=sumy+m_arrAutoSampleBakData[i].G;
}
}
btBestBakXMean=sumx/m_arrAutoSampleBakData.GetSize();
btBestBakYMean=sumy/m_arrAutoSampleBakData.GetSize();
//求取最优分类直线
*pXMeanVal=(btBestObjXMean + btBestBakXMean)/2;
*pYMeanVal=(btBestObjYMean + btBestBakYMean)/2;
if((btBestObjXMean==btBestBakXMean)&&(btBestObjYMean==btBestBakYMean))
{
AfxMessageBox("样本点选取有问题!");
return;
}
if(btBestObjXMean==btBestBakXMean)
{
m_bIsParallelWithXYAxis = PARALLEL_WITH_X_AXIS;
}
if(btBestObjYMean==btBestBakYMean)
{
m_bIsParallelWithXYAxis = PARALLEL_WITH_Y_AXIS;
}
if((btBestObjXMean!=btBestBakXMean) && (btBestObjYMean!=btBestBakYMean))
{
tmpf=(float)((float)(btBestObjYMean - btBestBakYMean))/((float)(btBestObjXMean - btBestBakXMean));
m_fA=(float)-1.0/tmpf;
BYTE tmpX,tmpY;
tmpX=(btBestObjXMean + btBestBakXMean)/2;
tmpY=(btBestObjYMean + btBestBakYMean)/2;
m_fB=tmpY - m_fA*tmpX;
}
}
void CDlgPatternRecog::DrawOptimizationClassifyLine(BYTE XMeanVal, BYTE YMeanVal)
{
CDC* pDC=m_lpTabDC;
CPen* pPen = new CPen;
pPen->CreatePen(PS_SOLID,2,RGB(255,0,0));
CGdiObject* pOldPen = pDC->SelectObject(pPen);
CPoint p1,p2; //与绘图边框的两个交点
long tmpX,tmpY;
switch(m_bIsParallelWithXYAxis)
{
case PARALLEL_WITH_X_AXIS:
GetTabXYFromLogicXY(0,YMeanVal,&tmpX,&tmpY);
p1=CPoint(tmpX,tmpY);
GetTabXYFromLogicXY(255,YMeanVal,&tmpX,&tmpY);
p2=CPoint(tmpX,tmpY);
break;
case PARALLEL_WITH_Y_AXIS:
GetTabXYFromLogicXY(XMeanVal,0,&tmpX,&tmpY);
p1=CPoint(tmpX,tmpY);
GetTabXYFromLogicXY(XMeanVal,255,&tmpX,&tmpY);
p2=CPoint(tmpX,tmpY);
break;
case PARALLEL_WITH_NO_AXIS:
GetTwoPointOfOptiLineWithAxisArea(&p1,&p2);
}
// 绘制
pDC->MoveTo(p1);
pDC->LineTo(p2);
pDC->SelectObject(pOldPen);
delete pPen;
}
// 计算直线和坐标轴二个交点坐标
void CDlgPatternRecog::GetTwoPointOfOptiLineWithAxisArea( CPoint *lpP1, CPoint *lpP2)
{
int x1,y1,x2,y2;
if (m_fA >= 0)
{
if (((m_fA * 255 + m_fB) >= 0) && (m_fB < 255))
{
// 计算(x1, y1)坐标
if (m_fB < 0)
{
x1 = (int) (- m_fB/m_fA + 0.5);
y1 = 0;
}
else
{
x1 = 0;
y1 = (int) (m_fB + 0.5);
}
// 计算(x2, y2)坐标
if ((m_fA * 255 + m_fB) > 255)
{
x2 = (int) ((255- m_fB)/m_fA + 0.5);
y2 = 255;
}
else
{
x2 = 255;
y2 = (int) (255* m_fA + m_fB + 0.5);
}
}
else if(((m_fA * 255 + m_fB) < 0))
{
// 转换后所有象素值都小于0,直接设置为0
x1 = 0;
y1 = 0;
x2 = 255;
y2 = 0;
}
else
{
// 转换后所有象素值都大于255,直接设置为255
x1 = 0;
y1 = 255;
x2 = 255;
y2 = 255;
}
} //m_fA>=0
else // 斜率小于0
{
if ((m_fB > 0) && (255* m_fA + m_fB < 255))
{
// 计算(x1, y1)坐标
if (m_fB > 255)
{
x1 = (int) ((255- m_fB)/m_fA + 0.5);
y1 = 255;
}
else
{
x1 = 0;
y1 = (int) (m_fB + 0.5);
}
// 计算(x2, y2)坐标
if ((m_fA * 255 + m_fB) < 0)
{
x2 = (int) (- m_fB/m_fA + 0.5);
y2 = 0;
}
else
{
x2 = 255;
y2 = (int) (255* m_fA + m_fB + 0.5);
}
}
else if (m_fB <=0)
{
// 转换后所有象素值都小于0,直接设置为0
x1 = 0;
y1 = 0;
x2 = 255;
y2 = 0;
}
else
{
// 转换后所有象素值都大于255,直接设置为255
x1 = 0;
y1 = 255;
x2 = 255;
y2 = 255;
}
}
//将得到的逻辑坐标转换成TAB坐标
GetTabXYFromLogicXY(x1,y1,&lpP1->x,&lpP1->y);
GetTabXYFromLogicXY(x2,y2,&lpP2->x,&lpP2->y);
}
void CDlgPatternRecog::OnMenuPatternEnableReal()
{
// TODO: Add your command handler code here
m_bIsEnabledRealTimeProcess=TRUE;
}
void CDlgPatternRecog::OnMenuPatternDisenableReal()
{
// TODO: Add your command handler code here
m_bIsEnabledRealTimeProcess=FALSE;
}
void CDlgPatternRecog::OnMenuPatternMultiModeAddthird()
{
// TODO: Add your command handler code here
// 隐藏手工识别样本显示元素
((CWnd*)GetDlgItem(IDC_STATIC_COVER_RECT))->ShowWindow(SW_SHOW);
((CWnd*)GetDlgItem(IDC_STATIC_COVER_RECT))->SetWindowText("多模式自动识别数据采样...");
m_lRButtonDown=RBUTTONDOWN_MUTI_MODE;
m_lAuotSampleMode=AUTOSAMPLE_ADDTHIRD;
m_lMultiModeEnabled=true;
}
void CDlgPatternRecog::GetMutilModeStaticsInfo(tagStatics *Obj, tagStatics *Bak, tagStatics *Third)
{
LONG x,y,z;
LONG sx,sy,sz;
int i,size;
//目标样本统计
x=y=z=0;
size=m_arrAutoSampleObjData.GetSize();
for(i=0;i<size;i++)
{
x=x+m_arrAutoSampleObjData[i].R;
y=y+m_arrAutoSampleObjData[i].G;
z=z+m_arrAutoSampleObjData[i].B;
}
Obj->MeanP.X=x/size;
Obj->MeanP.Y=y/size;
Obj->MeanP.Z=z/size;
sx=sy=sz=0;
for(i=0;i<size;i++)
{
// sx=sx+pow(m_arrAutoSampleObjData[i].R - Obj->MeanP.X , 2);
// sy=sy+pow(m_arrAutoSampleObjData[i].G - Obj->MeanP.Y , 2);
// sz=sz+pow(m_arrAutoSampleObjData[i].B - Obj->MeanP.Z , 2);
sx=sx+abs(m_arrAutoSampleObjData[i].R - Obj->MeanP.X);
sy=sy+abs(m_arrAutoSampleObjData[i].G - Obj->MeanP.Y);
sz=sz+abs(m_arrAutoSampleObjData[i].B - Obj->MeanP.Z);
}
//Obj->ERR=(long)sqrt((sx+sy+sz)/size);
Obj->ERR=(long)((sx+sy+sz)/size);
//背景样本统计
x=y=z=0;
size=m_arrAutoSampleBakData.GetSize();
for(i=0;i<size;i++)
{
x=x+m_arrAutoSampleBakData[i].R;
y=y+m_arrAutoSampleBakData[i].G;
z=z+m_arrAutoSampleBakData[i].B;
}
Bak->MeanP.X=x/size;
Bak->MeanP.Y=y/size;
Bak->MeanP.Z=z/size;
sx=sy=sz=0;
for(i=0;i<size;i++)
{
// sx=sx+pow(m_arrAutoSampleBakData[i].R - Bak->MeanP.X ,2);
// sy=sy+pow(m_arrAutoSampleBakData[i].G - Bak->MeanP.Y ,2);
// sz=sz+pow(m_arrAutoSampleBakData[i].B - Bak->MeanP.Z ,2);
sx=sx+abs(m_arrAutoSampleBakData[i].R - Bak->MeanP.X);
sy=sy+abs(m_arrAutoSampleBakData[i].G - Bak->MeanP.Y);
sz=sz+abs(m_arrAutoSampleBakData[i].B - Bak->MeanP.Z);
}
//Bak->ERR=(long)sqrt((sx+sy+sz)/size);
Bak->ERR=(long)((sx+sy+sz)/size);
//第三模式样本统计
x=y=z=0;
size=m_arrAutoSampleThirdData.GetSize();
for(i=0;i<size;i++)
{
x=x+m_arrAutoSampleThirdData[i].R;
y=y+m_arrAutoSampleThirdData[i].G;
z=z+m_arrAutoSampleThirdData[i].B;
}
Third->MeanP.X=x/size;
Third->MeanP.Y=y/size;
Third->MeanP.Z=z/size;
sx=sy=sz=0;
for(i=0;i<size;i++)
{
// sx=sx+pow(m_arrAutoSampleThirdData[i].R - Third->MeanP.X ,2);
// sy=sy+pow(m_arrAutoSampleThirdData[i].G - Third->MeanP.Y ,2);
// sz=sz+pow(m_arrAutoSampleThirdData[i].B - Third->MeanP.Z ,2);
sx=sx+abs(m_arrAutoSampleThirdData[i].R - Third->MeanP.X);
sy=sy+abs(m_arrAutoSampleThirdData[i].G - Third->MeanP.Y);
sz=sz+abs(m_arrAutoSampleThirdData[i].B - Third->MeanP.Z);
}
//Third->ERR=(long)sqrt((sx+sy+sz)/size);
Third->ERR=(long)((sx+sy+sz)/size);
}
void CDlgPatternRecog::MultiModeClassifyTransWhenAutoRecog(tagStatics Obj, tagStatics Bak, tagStatics Third)
{
BYTE R,G,B;
LONG mode;
long DistanceWithObj,DistanceWithBak,DistanceWithThird;
CImageSysZLF01App * lpCurrentApp=(CImageSysZLF01App *)AfxGetApp();
CImageSysZLF01Doc * pDoc=lpCurrentApp->GetCurDocument();
HDIB hDIB=pDoc->GetHDIB();
LPSTR lpImage=pDoc->GetDIBPtr(hDIB);
LPSTR lpPriImage=pDoc->m_pPrimitiveImage;
long lBitCount=((LPBITMAPINFOHEADER)lpImage)->biBitCount;
long lWidth =DIBWidth (lpImage);
long lHeight=DIBHeight(lpImage);
LPSTR lpDBitsData=FindDIBBits(lpImage); //得到实时数据
LPSTR lpPriDBitsData=FindDIBBits(lpPriImage); //得到原始数据
int i,j;
mode=IN_OBJECT_MODE;
for (i=0;i<lHeight;i++)
{
for(j=0;j<lWidth;j++)
{
LPSTR lpPriSrc=lpPriDBitsData+((lHeight-1-i)*lWidth+j)*(lBitCount/8);
LPSTR lpSrc =lpDBitsData+((lHeight-1-i)*lWidth+j)*(lBitCount/8);
B=(BYTE)*lpPriSrc;
G=(BYTE)*(lpPriSrc+1);
R=(BYTE)*(lpPriSrc+2);
//进行判别
//与目标的距离
DistanceWithObj =(long)sqrt(pow(R-Obj.MeanP.X,2) + pow(G-Obj.MeanP.Y,2) + pow(B-Obj.MeanP.Z,2));
DistanceWithBak =(long)sqrt(pow(R-Bak.MeanP.X,2) + pow(G-Bak.MeanP.Y,2) + pow(B-Bak.MeanP.Z,2));
DistanceWithThird=(long)sqrt(pow(R-Third.MeanP.X,2) + pow(G-Third.MeanP.Y,2) + pow(B-Third.MeanP.Z,2));
if(DistanceWithObj<=DistanceWithBak)
{
if(DistanceWithObj<=DistanceWithThird)
{
mode=IN_OBJECT_MODE;
}
else
{
mode=IN_THIRD_MODE;
}
}
else
{
if(DistanceWithBak<=DistanceWithThird)
{
mode=IN_BACKRD_MODE;
}
else
{
mode=IN_THIRD_MODE;
}
}
switch(mode)
{
case IN_OBJECT_MODE:
if(DistanceWithObj>3*Obj.ERR)
mode=IN_THIRD_MODE;
break;
case IN_BACKRD_MODE:
//if(DistanceWithBak>3*Bak.ERR)
// mode=IN_THIRD_MODE;
break;
case IN_THIRD_MODE :
if(DistanceWithThird>Third.ERR)
mode=IN_THIRD_MODE;
break;
}
//变换像素数值
switch(mode)
{
case IN_OBJECT_MODE:
*lpSrc =GetBValue(MODE_COLOR_01);
*(lpSrc+1)=GetGValue(MODE_COLOR_01);
*(lpSrc+2)=GetRValue(MODE_COLOR_01);
break;
case IN_BACKRD_MODE:
*lpSrc =GetBValue(MODE_COLOR_02);
*(lpSrc+1)=GetGValue(MODE_COLOR_02);
*(lpSrc+2)=GetRValue(MODE_COLOR_02);
break;
case IN_THIRD_MODE :
*lpSrc =GetBValue(MODE_COLOR_03);
*(lpSrc+1)=GetGValue(MODE_COLOR_03);
*(lpSrc+2)=GetRValue(MODE_COLOR_03);
}
}//for j
}//for i
return;
}
void CDlgPatternRecog::DrawCurSamplePoint(tagRGBVal rgb)
{
BYTE btXColVal,btYColVal;
switch (m_nWhichColorNoUse)
{
case COLOR_RED:
btXColVal=rgb.B;
btYColVal=rgb.G;
break;
case COLOR_GREEN:
btXColVal=rgb.R;
btYColVal=rgb.B;
break;
case COLOR_BLUE:
btXColVal=rgb.R;
btYColVal=rgb.G;
}
CDC* pDC=m_lpTabDC;
CPen* pPenRed = new CPen;
pPenRed->CreatePen(PS_SOLID,2,RGB(255,0, 0));
CGdiObject* pOldPen = pDC->SelectObject(pPenRed);
int CurX=m_ptFigureXY0.x + btXColVal;
int CurY=m_ptFigureXY0.y - btYColVal;
int dx,dy;
dx=dy=2;
pDC->MoveTo(CurX-dx,CurY-dy);
pDC->LineTo(CurX+dx,CurY+dy);
pDC->MoveTo(CurX-dx,CurY+dy);
pDC->LineTo(CurX+dx,CurY-dy);
pDC->SelectObject(pOldPen);
delete pPenRed;
}
void CDlgPatternRecog::OnMenuPr23ClassLinear()
{
// TODO: Add your command handler code here
m_lRButtonDown=RBUTTONDOWN_AUTO_MODE;//允许3类采样
m_b3ClassRecogEnabled=TRUE;
//m_bIsEnabledRealTimeProcess=TRUE;
}
void CDlgPatternRecog::OnMenuPr2Unenable3ClassLinear()
{
// TODO: Add your command handler code here
m_b3ClassRecogEnabled=FALSE;
//m_bIsEnabledRealTimeProcess=FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -