📄 videopro.cpp
字号:
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;
POINT StartPoint,EndPoint,MidPoint;
POINT* line=new POINT[MaxValue1.Value];
//如果直线为偏水平的,按列,下面按x检测
if((MaxValue1.AngleNumber>=45) && (MaxValue1.AngleNumber<=135))
{
for(x =w.LeftX;x<w.RightX;x++)
{
for(y =w.BottomY;y<w.TopY;y++)
{
// 指向源图像第j行,第i个象素的指针fabs
int temp=(int)(x*costab[MaxValue1.AngleNumber]+y*sintab[MaxValue1.AngleNumber] ) ;
if(temp<0)
//tt=int(m+fabs(temp));
tt=(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[cc].x=x;
line[cc].y=y;
cc++;
}
}
}
}
else//如果直线为偏竖直的,按行,并且下面按y来检测
{
for(y =w.BottomY;y<w.TopY;y++)
{
for(x =w.LeftX;x<w.RightX;x++)
{
int temp=(int)(x*costab[MaxValue1.AngleNumber]+y*sintab[MaxValue1.AngleNumber] ) ;
if(temp<0)
tt=(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[cc].x=x;
line[cc].y=y;
cc++;
}
}
}
}//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;
}
}
/*
if(MaxValue1.AngleNumber<90)
{
StartPoint.x=int(MidPoint.x-MaxValue1.Value*sintab[MaxValue1.AngleNumber]/2);
StartPoint.y=int(MidPoint.y+MaxValue1.Value*costab[MaxValue1.AngleNumber]/2);
EndPoint.x=int(MidPoint.x+MaxValue1.Value/2*sintab[MaxValue1.AngleNumber]);
EndPoint.y=int(MidPoint.y-MaxValue1.Value/2*costab[MaxValue1.AngleNumber]);
}
else
{
StartPoint.x=int(MidPoint.x-MaxValue1.Value*sintab[180-MaxValue1.AngleNumber]/2);
StartPoint.y=int(MidPoint.y-MaxValue1.Value*costab[180-MaxValue1.AngleNumber]/2);
EndPoint.x=int(MidPoint.x+MaxValue1.Value/2*sintab[180-MaxValue1.AngleNumber]);
EndPoint.y=int(MidPoint.y+MaxValue1.Value/2*costab[180-MaxValue1.AngleNumber]);
}
*/
m_StartPoint=StartPoint;
m_EndPoint=EndPoint;
delete[]line;
line=NULL;
GlobalUnlock(hbuf);
GlobalFree(hbuf);
GlobalUnlock(hDistAlpha);
GlobalFree(hDistAlpha);
return TRUE;
}
void CVideoPro::Convolution(float *fpData, float *fpKernel, float fCoef,
int nSize, unsigned char *nResult)
{
int i;
float Sum = 0, fResult;
//计算卷积
for(i = 0; i < nSize; i++)
{
Sum += fpData[i] * fpKernel[i];
}
//执行卷积后的结果
fResult = Sum / fCoef;
//求绝对值
fResult = (float)fabs(fResult);
//判断是否超过255
if(fResult > 255.0 )
{
// 直接赋值为255
fResult = 255.0;
}
//对卷积结果四舍五入,并转换成unsigned char类型作为最后返回结果
*nResult = (unsigned char) (fResult + 0.5);
}
////////////////////////////////////////////////////////////////////////
//BOOL TemplateOperation()
//----------------------------------------------------------------------
//基本功能:该函数用指定的模板(任意大小)来对图像数据区的数据进行模板操
// 作,参数nTempH指定模板的高度,参数nTempW指定模板的宽度,参数
// nTempXc和nTempYc指定模板的中心元素坐标,参数fpArray为指定模
// 板元素数组的指针,fCoef指定模板系数。
//----------------------------------------------------------------------
//参数说明:float *fpArray 指向模板数组的指针
// float fCoef 模板系数
// int nTempW 模板的宽度
// int nTempH 模板的高度
// int nTempXc 模板的中心元素X坐标 ( <= nTempW - 1)
// int nTempYc 模板的中心元素Y坐标 ( <= nTempH - 1)
// unsigned char *pData 图像数据指针
// int nWidthBytes 图像字节宽度
// int nX1 处理区域左边界
// int nY1 处理区域上边界
// int nX2 处理区域右边界
// int nY2 处理区域下边界
//----------------------------------------------------------------------
//返 回:BOOL
// 成功时返回TRUE,失败时返回FALSE。
//----------------------------------------------------------------------
//注 意:此函数声明为保护型,只能在CVideoPro类中使用。
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
BOOL CVideoPro::TemplateOperation(LPBYTE lpDIBBits,float *fpArray, float fCoef,
int nTempW, int nTempH, int nTempXc, int nTempYc,
int nX1, int nY1,
int nX2, int nY2,
int nHeight,int nWidth )
{
//定义变量
unsigned char Data;
unsigned char Result1,Result2;
//定义与图像数据操作有关的变量
unsigned char *pOldBits, *pNewBits,*pBufBits,
*pOldTemp, *pNewTemp,
*pNeighborTemp;
int x, y, i, j;
int dwNewSize;
//原图像数据指针LPBYTE lpDIBBits
pOldBits = (BYTE*)lpDIBBits;
HGLOBAL hNewDib,hBufDib;
//新图像文件大小(以字节为单位)
dwNewSize = nWidth * nHeight;
//为新图像分配内存
hNewDib = ::GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT, dwNewSize );
//内存分配失败
if( hNewDib == NULL )
return( FALSE );
//新图像指针
pNewBits = (unsigned char *) ::GlobalLock( hNewDib );
if( pNewBits == NULL )
{
::GlobalFree( hNewDib );
return( FALSE );
}
//为中转图像分配内存
hBufDib = ::GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT, dwNewSize );
//内存分配失败
if( hBufDib == NULL )
return( FALSE );
//中转图像指针
pBufBits = (unsigned char *) ::GlobalLock( hBufDib );
if( pBufBits == NULL )
{
::GlobalFree( hBufDib );
return( FALSE );
}
//复制图像数据
for(y = 0; y < nHeight; y++ )
{
for(x = 0; x < nWidth; x++ )
{
pBufBits[nWidth*y+x]=lpDIBBits[3*nWidth*y+3*x];
}
}
//定义卷积运算中用的临时数组 2个
float *pGray = new float [nTempW * nTempH];
if(pGray == NULL) return( NULL );
memset(pGray, 0, (nTempW * nTempH) * sizeof(float));
//行位置
for(y = nY1; y < nY2; y++ )
{
//原图像数据指针定位到起始位置
pOldTemp = pBufBits;
//原图像数据指针定位到图像数据每行的起始零位置(nHeight -1 - y)
pOldTemp += y* nWidth;
//原图像数据指针定位到图像数据每行的起始nX1-1位置
pOldTemp += nX1;
//新图像数据指针定位到起始位置
pNewTemp = pNewBits;
//新图像数据指针定位到图像数据每行的起始零位置(nHeight -1 - y)
pNewTemp += y * nWidth;
//新图像数据指针定位到图像数据每行的起始nX1位置
pNewTemp += nX1;
//列位置
for(x = nX1; x < nX2; x++)
{
//取出原图像nTempW×nTempH邻域内的像素值
for (i = 0; i < nTempH; i++)
{
for (j = 0; j < nTempW; j++)
{
//数据指针指向当前像素
pNeighborTemp = pOldTemp;
//数据指针指向原图像第y - nTempYc + i行。
pNeighborTemp += nWidth * (i-nTempYc);
//第x - nTempXc + j列像素的指针
pNeighborTemp += (j - nTempXc);
//获取像素值
Data = *pNeighborTemp;
pGray[i * nTempW + j] = (float)Data;
}
}
//卷积核尺寸
int nSize = nTempW * nTempH;
// float fpArray2[9]={1,2,1,0,0,0,-1,-2,-1};
// float fpArray2[9]={1,1.414,1,0,0,0,-1,-1.414,-1};
// float fpArray2[9]={-2,-1,0,-1,0,1,0,1,2};//45度方向算子
float fpArray2[9]={1,0,-1,2,0,-2,1,0,-1};
////作卷积
Convolution(pGray, fpArray, fCoef, nSize, &Result1);
Convolution(pGray, fpArray2, fCoef, nSize, &Result2);
if(Result1<Result2)
Result1=Result2;
//将计算结果赋于新图像
*pNewTemp = Result1;
/*
if(Result1+Result2>255)
*pNewTemp=255.0;
else
*pNewTemp = (Result1+Result2);
*/
//新旧图像数据指针加1
pOldTemp++;
pNewTemp++;
}
}
//释放内存
delete [] pGray;
//复制图像数据
//复制图像数据
for(y = 0; y < nHeight; y++ )
{
for(x = 0; x < nWidth; x++ )
{
pOldBits[3*nWidth*y+3*x]=\
pOldBits[3*nWidth*y+3*x+1]=\
pOldBits[3*nWidth*y+3*x+2]=pNewBits[nWidth*y+x];
}
}
lpDIBBits= (LPBYTE)pOldBits;
::GlobalUnlock( hNewDib );
::GlobalFree( hNewDib );
::GlobalUnlock( hBufDib );
::GlobalFree( hBufDib );
return( TRUE );
}
BOOL CVideoPro::TempSobel(LPBYTE lpDIBBits, int lHeight, int lWidth,WINDOW w)
{
// 模板高度
int nTempH;
// 模板宽度
int nTempW;
// 模板系数
float fTempC;
// 模板中心元素X坐标
int nTempXc;
// 模板中心元素Y坐标
int nTempYc;
int nX1=-1, nY1=-1, nX2=-1, nY2=-1;
// 模板元素数组
// float aValue[9]={-1.0,0,1.0,-1.414,0,1.414,-1.0,0,1.0};//正边缘90方向算子
// float aValue[9]={0,1,2,-1,0,1,-2,-1,0};//135度方向检测算子
//float aValue[9]={1,0,0,0,-1,0,0,0,0};Rorbets算子
float aValue[9]={1,2,1,0,0,0,-1,-2,-1};
nTempH=3;
nTempW=3;
fTempC=1.0;
nTempXc=1;
nTempYc=1;
//对边界像素不作处理
if( nX1 < nTempXc+w.LeftX ) nX1 = nTempXc+w.LeftX;
if( nY1 < nTempYc+w.BottomY ) nY1 = nTempYc+w.BottomY;
if( nX2 < w.RightX - nTempW + nTempXc + 1)
nX2 = w.RightX- nTempW + nTempXc + 1;
if( nY2 < w.TopY - nTempH + nTempYc + 1)
nY2 = w.TopY - nTempH + nTempYc + 1;
TemplateOperation(lpDIBBits,aValue, fTempC,
nTempW, nTempH, nTempXc, nTempYc,
nX1, nY1,
nX2, nY2,
lHeight,lWidth );
return TRUE;
}
//腐蚀运算
void CVideoPro::Erosion(LPBYTE lpDIBBits, int lHeight, int lWidth)
{
//循环变量
LONG i;
LONG j;
LONG m;
LONG n;
// 指向源图像的指针
LPBYTE lpSrc;
// 指向缓存图像的指针
LPBYTE lpDst;
// 指向缓存DIB图像的指针
LPBYTE lpNewDIBBits;
HLOCAL hNewDIBBits;
// 计算图像每行的字节数
LONG lLineBytes = lWidth * 3;
// 暂时分配内存,以保存新图像
hNewDIBBits = LocalAlloc(LHND, lLineBytes * lHeight);
if (hNewDIBBits == NULL)
{
// 分配内存失败
return;
}
// 锁定内存
lpNewDIBBits = (LPBYTE)LocalLock(hNewDIBBits);
// 初始化新分配的内存,设定初始值为255
lpDst = (LPBYTE)lpNewDIBBits;
memset(lpDst, (BYTE)255, lLineBytes * lHeight);
// 3×3的结构元素
int T[9] = {0, 1, 0,
1, 1, 1,
0, 1, 0};
// 使用水平方向的结构元素进行腐蚀
for (i = 1; i < lHeight - 1; i++)
{
for (j = 3; j < lLineBytes - 3; j += 3)
{
// 由于使用3×3的结构元素,为防止越界,所以不处理最左、右、上、下四边的像素
// 指向源图像倒数第j行,第i个象素的指针
lpSrc = (unsigned char *)(lpDIBBits + lLineBytes * i + j);
// 指向目标图像倒数第j行,第i个象素的指针
lpDst = (unsigned char *)(lpNewDIBBits + lLineBytes * i + j);
// 目标图像中的当前点先赋成bai色
*lpDst = 255;
*(lpDst + 1) = 255;
*(lpDst + 2) = 255;
// 如果源图像中3×3结构元素对应位置有白点
// 则将目标图像中的(0,0)点赋成hei色
for (m = 0; m < 3; m++)
{
for (n = 0; n < 3; n++)
{
if (T[m * 3 + n] == 0)
continue;
if (*(lpSrc + (1 - m) * lLineBytes +(n - 1) * 3) < 128)
{
*lpDst = 0;
*(lpDst + 1) = 0;
*(lpDst + 2) = 0;
break;
}
}
}
}
}
// 复制腐蚀后的图像
memcpy(lpDIBBits, lpNewDIBBits, lLineBytes * lHeight);
// 释放内存
LocalUnlock(hNewDIBBits);
LocalFree(hNewDIBBits);
}
//膨胀Dilation
void CVideoPro::Dilation(LPBYTE lpDIBBits, int lHeight, int lWidth)
{
//循环变量
LONG i;
LONG j;
LONG m;
LONG n;
// 指向源图像的指针
LPBYTE lpSrc;
// 指向缓存图像的指针
LPBYTE lpDst;
// 指向缓存DIB图像的指针
LPBYTE lpNewDIBBits;
HLOCAL hNewDIBBits;
// 计算图像每行的字节数
LONG lLineBytes =lWidth *3;
// 暂时分配内存,以保存新图像
hNewDIBBits = LocalAlloc(LHND, lLineBytes * lHeight);
if (hNewDIBBits == NULL)
{
// 分配内存失败
return;
}
// 锁定内存
lpNewDIBBits = (LPBYTE)LocalLock(hNewDIBBits);
// 初始化新分配的内存,设定初始值为255
lpDst = (LPBYTE)lpNewDIBBits;
memset(lpDst, (BYTE)255, lLineBytes * lHeight);
// 3×3的结构元素
int T[9] = {0, 1, 0,
1, 1, 1,
0, 1, 0};
// 使用水平方向的结构元素进行腐蚀
for (i = 1; i < lHeight - 1; i++)
{
for (j = 3; j < lLineBytes - 3; j += 3)
{
// 由于使用3×3的结构元素,为防止越界,所以不处理最左、右、上、下四边的像素
// 指向源图像倒数第j行,第i个象素的指针
lpSrc = (unsigned char *)(lpDIBBits + lLineBytes * i + j);
// 指向目标图像倒数第j行,第i个象素的指针
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -