📄 videopro.cpp
字号:
}
}//else end
//注意坐标系
MidPoint=line[int(MaxValue1.Value/2)];
int g,p;
int lenx,leny;
g=10;
//按列来检测,距离g=x/sin(theta)
if(MaxValue1.AngleNumber>=45 && MaxValue1.AngleNumber<=135)
{
for(p=int(MaxValue1.Value/2);p>1;p--)
{
lenx=(line[p].x-line[p-1].x)/sintab[MaxValue1.AngleNumber];
if ( lenx<g )
StartPoint=line[p-1];
else
break;
}
for(p=int(MaxValue1.Value/2);p<MaxValue1.Value-1;p++)
{
lenx=(line[p+1].x-line[p].x)/sintab[MaxValue1.AngleNumber];
if (lenx<g)
EndPoint=line[p+1];
else
break;
}
}
else//按行来检测,距离g=y/cos(theta)
{
for(p=int(MaxValue1.Value/2);p>1;p--)
{
leny=(line[p].y-line[p-1].y)/fabs(costab[MaxValue1.AngleNumber]);
if ( leny<g )
StartPoint=line[p-1];
else
break;
}
for(p=int(MaxValue1.Value/2);p<MaxValue1.Value-1;p++)
{
leny=(line[p+1].y-line[p].y)/fabs(costab[MaxValue1.AngleNumber]);
if (leny<g)
EndPoint=line[p+1];
else
break;
}
}
m_StartPoint=StartPoint;
m_EndPoint=EndPoint;
delete[]line;
GlobalUnlock(hbuf);
GlobalFree(hbuf);
GlobalUnlock(hDistAlpha);
GlobalFree(hDistAlpha);
return TRUE;
}
void CVideoPro::GetCoreRegion(LPBYTE lpDIBBits, int lHeight, int lWidth, LUV *luv)
{
WINDOW w;
RGB rgb;
int i,j;
w.LeftX=int(0.4*lWidth);
w.BottomY=int(0.1*lHeight);
w.RightX=int(0.5*lWidth);
w.TopY=int(0.3*lHeight);
double SumL,SumU,SumV;
SumL=SumU=SumV=0;
LUV TempLuv;
for (i = w.BottomY; i < w.TopY; i ++)
{
for (j = w.LeftX; j <w.RightX; j ++)
{
// 获取各颜色分量
unsigned char B= *((unsigned char *)lpDIBBits + 3*lWidth * i + 3*j);
unsigned char G = *((unsigned char *)lpDIBBits + 3*lWidth* i+ 3*j+1);
unsigned char R = *((unsigned char *)lpDIBBits + 3*lWidth* i + 3*j+2);
rgb.r=R;
rgb.g=G;
rgb.b=B;
RgbToLuv(&rgb,&TempLuv);
SumL=SumL+TempLuv.l;
SumU=SumU+TempLuv.u;
SumV=SumV+TempLuv.v;
}
}
luv->l=(double)SumL/double(( w.TopY-w.BottomY)*(w.RightX-w.LeftX));
luv->u=(double)SumU/double(( w.TopY-w.BottomY)*(w.RightX-w.LeftX));
luv->v=(double)SumV/double(( w.TopY-w.BottomY)*(w.RightX-w.LeftX));
}
//水平边缘判断,是否为障碍物与地面的交线
BOOL CVideoPro::HorizonEdgeJudge(LPBYTE lpDIBBits, LUV CoreLuv, int lHeight, int lWidth, int row, int col, int Len)
{
int i,k;
k=2*Len;
int sumUp,sumDown;
RGB rgb;
LUV luv;
double dist;
sumUp=sumDown=0;
for (i = 0; i <k; i++)
{
unsigned char B =*((unsigned char *)lpDIBBits+(row+i-Len)*3*lWidth+3*col);
unsigned char G =*((unsigned char *)lpDIBBits+(row+i-Len)*3*lWidth+3*col+1);
unsigned char R =*((unsigned char *)lpDIBBits+(row+i-Len)*3*lWidth+3*col+2);
rgb.r=R;
rgb.g=G;
rgb.b=B;
double l0,u0,v0,rp;
l0=CoreLuv.l;
u0=CoreLuv.u;
v0=CoreLuv.v;
RgbToLuv(&rgb,&luv);
rp=sqrt((luv.l-l0)*(luv.l-l0)+(luv.u-u0)*(luv.u-u0)+(luv.v-v0)*(luv.v-v0));
dist=15.0;
if(i<Len && rp<dist)sumDown++;
if(i>Len && rp<dist)sumUp++;
}
if((sumDown-sumUp)>0)
return TRUE;
else
return FALSE;
}
BOOL CVideoPro::ToGray(LPBYTE lpBytes, int lHeight, int lWidth, WINDOW w)
{
int i,j;
// 对各像素进行灰度转换
// 计算图像每行的字节数
for (i = w.BottomY; i < w.TopY; i ++)
{
for (j = w.LeftX; j <w.RightX; j ++)
{
// 获取各颜色分量
unsigned char B= *((unsigned char *)lpBytes + 3*lWidth * i + 3*j);
unsigned char G = *((unsigned char *)lpBytes + 3*lWidth* i+ 3*j+1);
unsigned char R = *((unsigned char *)lpBytes + 3*lWidth* i + 3*j+2);
// 计算灰度值
unsigned char Y = (77 * R + 150 * G + 29 * B) / 256;
// unsigned char U = 128+(-44 * R -87* G + 131* B)/256 ;
// unsigned char V = 128+(131 * R - 110 * G -21 * B)/256 ;
// 回写灰度值
*((unsigned char *)lpBytes + 3*lWidth* i + 3*j) = Y;
*((unsigned char *)lpBytes + 3*lWidth* i+ 3*j+1) = Y;
*((unsigned char *)lpBytes + 3*lWidth* i+ 3*j+2) = Y;
}
}
return TRUE;
}
BOOL CVideoPro::RapidSobel(LPBYTE lpDIBBits, int lHeight, int lWidth)
{
int x,y;
double fx,fy,a1,a2,a;
BYTE *pTempImage=new BYTE[lWidth*lHeight*3];
memcpy(pTempImage,lpDIBBits,lWidth*lHeight*3);
for(y=1;y<lHeight-1;y++)
{
for(x=1;x<lWidth-1;x++)
{
fx= lpDIBBits[(x-1)*3+3*(y+1)*lWidth]
+2*lpDIBBits[x*3+3*(y+1)*lWidth]
+lpDIBBits[(x+1)*3+3*(y+1)*lWidth]
-lpDIBBits[(x-1)*3+3*(y-1)*lWidth]
-2*lpDIBBits[x*3+3*(y-1)*lWidth]
-lpDIBBits[(x+1)*3+3*(y-1)*lWidth];
fy= lpDIBBits[(x-1)*3+3*(y-1)*lWidth]
+2*lpDIBBits[(x-1)*3+3*y*lWidth]
+lpDIBBits[(x-1)*3+3*(y+1)*lWidth]
-lpDIBBits[(x+1)*3+3*(y-1)*lWidth]
-2*lpDIBBits[(x+1)*3+3*y*lWidth]
-lpDIBBits[(x+1)*3+3*(y+1)*lWidth];
//a=fx>0?fx:-fx+fy>0?fy:-fy;
a1=fx>0?fx:-fx;
a2=fy>0?fy:-fy;
a=a1>a2?a1:a2;
// a=fx>fy?fx:fy;
pTempImage[3*y*lWidth+3*x]=
pTempImage[3*y*lWidth+3*x+1]=
pTempImage[3*y*lWidth+3*x+2]=BYTE(a);
//a>255?255:a;
}
}
memcpy(lpDIBBits,pTempImage,lWidth*lHeight*3);
delete []pTempImage;
pTempImage=NULL;
return TRUE;
}
BOOL CVideoPro::RapidSobel(LPBYTE lpDIBBits, int *lpAngleData, int lHeight, int lWidth)
{
int x,y;
double fx,fy,a1,a2,a,angle,t;
double tan1,tan2;
BYTE *pTempImage=new BYTE[lWidth*lHeight*3];
for(y=1;y<lHeight-1;y++)
{
for(x=1;x<lWidth-1;x++)
{
fx= lpDIBBits[(x-1)*3+3*(y+1)*lWidth]
+2*lpDIBBits[x*3+3*(y+1)*lWidth]
+lpDIBBits[(x+1)*3+3*(y+1)*lWidth]
-lpDIBBits[(x-1)*3+3*(y-1)*lWidth]
-2*lpDIBBits[x*3+3*(y-1)*lWidth]
-lpDIBBits[(x+1)*3+3*(y-1)*lWidth];
fy= lpDIBBits[(x-1)*3+3*(y-1)*lWidth]
+2*lpDIBBits[(x-1)*3+3*y*lWidth]
+lpDIBBits[(x-1)*3+3*(y+1)*lWidth]
-lpDIBBits[(x+1)*3+3*(y-1)*lWidth]
-2*lpDIBBits[(x+1)*3+3*y*lWidth]
-lpDIBBits[(x+1)*3+3*(y+1)*lWidth];
//fx=1.0;
// fy=-1.732;
a1=fx>0?fx:-fx;
a2=fy>0?fy:-fy;
// arctan(x) = x - x3/3 + x5/5 - x7/7 + .... (2)
t=a1>a2?(a2/a1):(a1/a2);//abs(t)<1
tan1=t-t*t*t/3+t*t*t*t*t/5-t*t*t*t*t*t*t/7;
if(fx/fy>0)
angle=(a1>a2)?tan1:(PI/2-tan1);
else
{
angle=(a1>a2)?(PI-tan1):(PI-(PI/2-tan1));
}
// angle=atan2(a2,a1)>0?(atan2(a2,a1)*180/PI):(180+atan2(a2,a1)*180/PI);
lpAngleData[y*lWidth+x]=int(angle*180/PI);
a=a1>a2?a1:a2;
// a=fx>fy?fx:fy;
pTempImage[3*y*lWidth+3*x]=
pTempImage[3*y*lWidth+3*x+1]=
pTempImage[3*y*lWidth+3*x+2]=(BYTE)a;
//a>255?255:a;
}
}
memcpy(lpDIBBits,pTempImage,lWidth*lHeight*3);
delete []pTempImage;
pTempImage=NULL;
return TRUE;
}
BOOL CVideoPro::NEWHough(LPBYTE lpDIBBits, int *lpAngleData, int lHeight, int lWidth, WINDOW w)
{
BYTE *lpSrc;
MaxValue MaxValue1;
int iMaxAngleNumber;
int iDist;
int step_distance=1;//步进距离
double step_angle=PI/180;//步进角
//循环变量
int i,k,m;
long s;
int x;
int y;
double sintab[180],costab[180];
for(x=0;x<180;x++)
{
sintab[x]=sin(x*PI/180);
costab[x]=cos(x*PI/180);
}
//存储变换域中的两个最大值
//计算变换域的尺寸
m = (int) (sqrt(lWidth*lWidth + lHeight*lHeight)/step_distance);
//角度从0-180,每格step_angle 度
iMaxAngleNumber = int(PI/step_angle);
int *buf,**lpTransArea;
HGLOBAL hbuf,hDistAlpha;
//分配内存用来处理数据
if(( hbuf=GlobalAlloc(GHND,2*m*iMaxAngleNumber* sizeof(int)))==NULL){
//MessageBox(hWnd,"Error alloc memory!","Error Message",MB_OK|MB_ICONEXCLAMATION);
return FALSE;
}
buf=(int *)GlobalLock(hbuf);
//分配内存用来处理数据
if(( hDistAlpha=GlobalAlloc(GHND,2*m* sizeof(int)))==NULL){
//MessageBox(hWnd,"Error alloc memory!","Error Message",MB_OK|MB_ICONEXCLAMATION);
return FALSE;
}
lpTransArea=(int **)GlobalLock(hDistAlpha);
for(i=0;i<2*m;i++)
{
lpTransArea[i]=buf+i*180;//置每行的首地址,每行180度
memset(lpTransArea[i],0,180);//计数单元初始化为零
}
// 计算图像每行的字节数
LONG lLineBytes = 3*lWidth ;
int ang;
int count=0;
for(y =w.BottomY;y<w.TopY;y++)
{
for(x =w.LeftX;x<w.RightX;x++)
{
// 指向源图像第j行,第i个象素的指针
lpSrc = (BYTE *)(lpDIBBits + lLineBytes * y + 3*x);
//如果是白点,则在变换域的对应各点上加1
if( *lpSrc==255)
{ //注意步长
ang=lpAngleData[lWidth * y +x];
if( ang<=w.MaxAngle && ang>=w.MinAngle)
{
for(k=w.MinAngle; k<w.MaxAngle;k++)
{ //计算距离:
s =(long)(x*costab[k]+y*sintab[k]);
//变换域的对应点上加1
if(s>=0)
lpTransArea[s][k]++;
else
// lpTransArea[int(fabs(s))+m][k]++;
lpTransArea[int(s+2*m)][k]++;
}
}
}
}
}
//找到变换域中的最大值点 && fabs(k-90)>5
MaxValue1.Value=0;
//找到第一个最大值点
for (iDist=0; iDist<2*m;iDist++)
{
for(k=w.MinAngle; k<w.MaxAngle;k++)
{
if(lpTransArea[iDist][k]>MaxValue1.Value)
{
MaxValue1.Value = lpTransArea[iDist][k];
MaxValue1.Dist = iDist;
MaxValue1.AngleNumber = k;
}
}
}
m_HoughPara=MaxValue1;
int tt;
int cc=0;
// XIANDUAN StartPoint,EndPoint,BufPoint;
//XIANDUAN* line=new XIANDUAN[MaxValue1.Value];
int line[288];
memset(line,0,sizeof(line));
for(y =w.BottomY;y<w.TopY;y++)
{
for(x =w.LeftX;x<w.RightX;x++)
{
// 指向源图像第j行,第i个象素的指针fabs
int temp=(long)(x*costab[MaxValue1.AngleNumber]+y*sintab[MaxValue1.AngleNumber] ) ;
if(temp<0)
//tt=int(m+fabs(temp));
tt=int(2*m+temp);
else
tt=temp;
//
if( MaxValue1.Dist==tt &&( *(lpDIBBits + lLineBytes * y +3*x)==255) )
{
*(lpDIBBits + lLineBytes * y +3*x)=0;
*(lpDIBBits + lLineBytes * y +3*x+1)=255;
*(lpDIBBits + lLineBytes * y +3*x+2)=0;
line[x]=1;
}
/* else
{
*(lpDIBBits + lLineBytes * y +3*x)=0;
*(lpDIBBits + lLineBytes * y +3*x+1)=0;
*(lpDIBBits + lLineBytes * y +3*x+2)=0;
}
*/
}
}
/*
int tc=0;
do
{
//if ( (line[i]-line[0])>=i && (line[i]-line[0])<=i+3 )
do
{
if(line[i]==0)
i++;
tc=i;
else
break;
}while(i<288 )
StartPoint.x=line[tc];
do
{
i=tc;
if(line[i]==1)
{
i++;
}
}
// break;
}
tc++;
}
*/
GlobalUnlock(hbuf);
GlobalFree(hbuf);
GlobalUnlock(hDistAlpha);
GlobalFree(hDistAlpha);
// 释放内存
// delete[] lpTransArea;
return TRUE;
}
BOOL CVideoPro::InteEqualize(LPBYTE lpBytes, int lHeight, int lWidth)
{
int i,j;
int* pHistogram=new int[256];
memset(pHistogram, 0, 256);
unsigned char *pTemp;
int x, y;
// 灰度映射表
BYTE bMap[256];
//memset(bMap,0,256);
for(i = 0; i < 256; i++)
{
bMap[i] = 0;
}
for (i = 0; i < lHeight; i ++)
{
for (j = 0; j < lWidth; j ++)
{
// 获取各颜色分量
unsigned char B= *((unsigned char *)lpBytes + 3*lWidth * i + 3*j);
unsigned char G = *((unsigned char *)lpBytes + 3*lWidth* i+ 3*j+1);
unsigned char R = *((unsigned char *)lpBytes + 3*lWidth* i + 3*j+2);
// 计算灰度值
unsigned char Y = (77 * R + 150 * G + 29 * B) / 256;
// unsigned char U = 128+(-44 * R -87* G + 131* B)/256 ;
// unsigned char V = 128+(131 * R - 110 * G -21 * B)/256 ;
pHistogram[Y]++;
// 回写灰度值
*((unsigned char *)lpBytes + 3*lWidth* i + 3*j) =Y ;
*((unsigned char *)lpBytes + 3*lWidth* i+ 3*j+1) = Y;
*((unsigned char *)lpBytes + 3*lWidth* i+ 3*j+2) = Y;
}
}
// 计算灰度映射表
for (i = 0; i < 256; i++)
{
// 初始为0
long lTemp = 0;
for (j = 0; j <= i ; j++)
{
lTemp += pHistogram[j];
}
// 计算对应的新灰度值* 255/lHeight / lWidth
bMap[i] = (BYTE) (lTemp*255/lHeight / lWidth );
}
delete [] pHistogram;
for(y = 0; y < lHeight; y++)
{
pTemp = lpBytes;
pTemp += y * 3*lWidth; //位图数据下一行起始指针
for(x = 0; x < lWidth; x++)
{
long lpSrc = pTemp[3*x];
// 计算新的灰度值
pTemp[3*x]=pTemp[3*x+1]=pTemp[3*x+2] = bMap[lpSrc];
}
}
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -