求二值图像目标区域并求各个区域的面积源码?

hyw1980 2004-07-27 03:47:11
我在用8链码寻目标图像连通区域并计算面积时,程序编译通过,但是在处理时总是跳不循环。请各位过路高手帮忙指点一下!不胜感激!
代码如下:
//八个方向和起始扫描方向
int Direction[8][2]={{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1},{0,1},{1,1}};
int BeginDirect=0;

StartPoint.Height=0;
StartPoint.Width =0;
col=(unsigned char)0;
for(k=0;k<100;k++)
{
biFindStartPoint=false;
//*(area+col)=0;
for (j = StartPoint.Height;j < lHeight && !biFindStartPoint;j++)
{
for(i =StartPoint.Width;i < lWidth && !biFindStartPoint;i++)
{
// 指向源图像倒数第j行,第i个象素的指针
lpSrc = (char *)lpDIBBits + lLineBytes * j + i;
lpDst = (char *)lpNewDIBBits+ lLineBytes * j + i;
pixel = (unsigned char)*lpSrc;

if(((unsigned char)*lpDst)==255)
{
if(pixel == 0)
{
//找到初始点
biFindStartPoint = true;

StartPoint.Height = j;
StartPoint.Width = i;

*lpDst = (unsigned char)col;
//初步判断
nw = (unsigned char)*(lpSrc + 6*lLineBytes +6);
n = (unsigned char)*(lpSrc + 3*lLineBytes +3);
ne = (unsigned char)*(lpSrc + 9*lLineBytes +9);
if(nw+n+ne!=0)biFindStartPoint = false;

}
}
}
}
CurrentPoint.Height=StartPoint.Height;
CurrentPoint.Width =StartPoint.Width ;
//区域连通求面积
count=1;
biFindStartPoint = false;
while( !biFindStartPoint)
{
BeginDirect=0;
biFindPoint= false;
while(!biFindPoint)
{
//沿扫描方向查看一个像素
lpSrc = (char *)lpDIBBits + lLineBytes * ( CurrentPoint.Height + Direction[BeginDirect][1])
+ (CurrentPoint.Width + Direction[BeginDirect][0]);
pixel = (unsigned char)*lpSrc;
//if the memory point is never marked,
lpDst = (char *)lpNewDIBBits + lLineBytes * ( CurrentPoint.Height + Direction[BeginDirect][1])
+ (CurrentPoint.Width + Direction[BeginDirect][0]);
if(((unsigned char)(*lpDst)==255))
{
if(pixel == 0)
{
biFindPoint = true;

CurrentPoint.Height = CurrentPoint.Height + Direction[BeginDirect][1];
CurrentPoint.Width = CurrentPoint.Width + Direction[BeginDirect][0];

*lpDst = (unsigned char)col;
count++;
*(area+col)=count;
}
else
{
BeginDirect++;
if(BeginDirect == 8)
{
BeginDirect = 0;
//如果当前点周围的八个点都是已经找到过的点,结束该区域循环
lpDst = (char *)lpNewDIBBits + lLineBytes * CurrentPoint.Height + CurrentPoint.Width;
if(((unsigned char)*(lpDst - lLineBytes-1 )+(unsigned char)*(lpDst - lLineBytes )+(unsigned char)*(lpDst - lLineBytes +1)
+(unsigned char)*(lpDst -1)+(unsigned char)*(lpDst )+(unsigned char)*(lpDst + 1)
+(unsigned char)*(lpDst + lLineBytes-1 )+(unsigned char)*(lpDst + lLineBytes )+(unsigned char)*(lpDst + lLineBytes+1))==9*col)
{
biFindStartPoint=true;
biFindPoint = true;
}
}
}
}
}//
}
col++;
}
...全文
309 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
huanyun 2004-07-31
  • 打赏
  • 举报
回复
else
{
//扫描方向顺时针旋转一格
BeginDirect++;
if(BeginDirect == 8) BeginDirect = 0;
}
}
else
{
BeginDirect++;
if(BeginDirect == 8) BeginDirect = 0;
}
}
}
}
else if(nBitCount == 1)
{
BYTE mask;
if(Value>0)
{
memset(pTraceBits, 0, lRowLen * lHeight);
bFindStartPoint = FALSE; //先找到最左上方的边界点
for (j=rcTrans.top;(j<rcTrans.bottom&& !bFindStartPoint);j++)
{
for(i=rcTrans.left;(i<rcTrans.right && !bFindStartPoint);i++)
{
bPixel = *(pSrcBits + lRowLen * j + i/8);
mask = 0x80>>(i%8);
if(bPixel&mask)
{
bFindStartPoint = TRUE;
StartPoint.Height = j;
StartPoint.Width = i;
*(pTraceBits + lRowLen * j + i/8) |= 0X80>>(i%8);
}
}
}
if(!bFindStartPoint) return FALSE; //起点
BeginDirect = 0;
bFindStartPoint = FALSE;
CurrentPoint.Height = StartPoint.Height;
CurrentPoint.Width = StartPoint.Width;
int xOffset;
int yOffset;
while(!bFindStartPoint)
{
bFindPoint = FALSE;
while(!bFindPoint)
{
xOffset = (CurrentPoint.Width + Direction[BeginDirect][0]);
yOffset = (CurrentPoint.Height + Direction[BeginDirect][1]);
if(xOffset>=rcTrans.left && xOffset<rcTrans.right && yOffset>=rcTrans.top && yOffset<rcTrans.bottom)
{
bPixel = *(pSrcBits + lRowLen * yOffset + xOffset/8);
mask = 0x80>>(xOffset%8);
if(bPixel&mask)
{
bFindPoint = TRUE;
CurrentPoint.Height = CurrentPoint.Height + Direction[BeginDirect][1];
CurrentPoint.Width = CurrentPoint.Width + Direction[BeginDirect][0];
if(CurrentPoint.Height == StartPoint.Height && CurrentPoint.Width == StartPoint.Width)
{
bFindStartPoint = TRUE;
}
pTrace = pTraceBits + lRowLen * CurrentPoint.Height + CurrentPoint.Width/8;
*pTrace |= 0x80>>(CurrentPoint.Width%8);
lGirth++;
//扫描的方向逆时针旋转两格
BeginDirect--;
if(BeginDirect == -1) BeginDirect = 7;
BeginDirect--;
if(BeginDirect == -1) BeginDirect = 7;
}
else
{
//扫描方向顺时针旋转一格
BeginDirect++;
if(BeginDirect == 8) BeginDirect = 0;
}
}
else
{
BeginDirect++;
if(BeginDirect == 8) BeginDirect = 0;
}
}
}
}
else
{
memset(pTraceBits, 255, lRowLen * lHeight);
bFindStartPoint = FALSE; //先找到最左上方的边界点
for (j=rcTrans.top;(j<rcTrans.bottom&& !bFindStartPoint);j++)
{
for(i=rcTrans.left;(i<rcTrans.right && !bFindStartPoint);i++)
{
bPixel = *(pSrcBits + lRowLen * j + i/8);
mask = 0x80>>(i%8);
if((bPixel&mask)==0)
{
bFindStartPoint = TRUE;
StartPoint.Height = j;
StartPoint.Width = i;
*(pTraceBits + lRowLen * j + i/8) &= ~(0X80>>(i%8));
}
}
}
if(!bFindStartPoint) return FALSE; //起点
BeginDirect = 0;
bFindStartPoint = FALSE;
CurrentPoint.Height = StartPoint.Height;
CurrentPoint.Width = StartPoint.Width;
int xOffset;
int yOffset;
while(!bFindStartPoint)
{
bFindPoint = FALSE;
while(!bFindPoint)
{
xOffset = (CurrentPoint.Width + Direction[BeginDirect][0]);
yOffset = (CurrentPoint.Height + Direction[BeginDirect][1]);
if(xOffset>=rcTrans.left && xOffset<rcTrans.right && yOffset>=rcTrans.top && yOffset<rcTrans.bottom)
{
bPixel = *(pSrcBits + lRowLen * yOffset + xOffset/8);
mask = 0x80>>(xOffset%8);
if((bPixel&mask)==0)
{
bFindPoint = TRUE;
CurrentPoint.Height = CurrentPoint.Height + Direction[BeginDirect][1];
CurrentPoint.Width = CurrentPoint.Width + Direction[BeginDirect][0];
if(CurrentPoint.Height == StartPoint.Height && CurrentPoint.Width == StartPoint.Width)
{
bFindStartPoint = TRUE;
}
pTrace = pTraceBits + lRowLen * CurrentPoint.Height + CurrentPoint.Width/8;
*pTrace &= ~(0x80>>(CurrentPoint.Width%8));
lGirth++;
//扫描的方向逆时针旋转两格
BeginDirect--;
if(BeginDirect == -1) BeginDirect = 7;
BeginDirect--;
if(BeginDirect == -1) BeginDirect = 7;
}
else
{
//扫描方向顺时针旋转一格
BeginDirect++;
if(BeginDirect == 8) BeginDirect = 0;
}
}
else
{
BeginDirect++;
if(BeginDirect == 8) BeginDirect = 0;
}
}
}
}
}
return lGirth;
}
huanyun 2004-07-31
  • 打赏
  • 举报
回复

//////////////////////////////////////////////////////////////////////
// 边缘跟踪
// BYTE* pTraceBits 目标图象素
// BYTE* pSrcBits 源图象素
// int nWidth, int nHeight 源图宽高(象素单位)
// int nBitCount 源图位数
// BYTE Value, 查找的象素值
// int left, int top, int right, int bottom 处理区域
///////////////////////////////////////////////////////////////////////


LONG XImgApi::Trace(BYTE* pTraceBits, BYTE* pSrcBits,
LONG lWidth, LONG lHeight, int nBitCount, BYTE Value,
int left, int top, int right, int bottom)
{
RECT rcTrans;
rcTrans.left = left;
rcTrans.right = right;
rcTrans.top = top;
rcTrans.bottom= bottom;
return Trace(pTraceBits, pSrcBits, lWidth, lHeight, nBitCount, Value, rcTrans);
}

LONG XImgApi::Trace(BYTE* pTraceBits, BYTE* pSrcBits,
LONG lWidth, LONG lHeight, int nBitCount, BYTE Value,
RECT rcTrans)
{
if(pTraceBits==NULL && pSrcBits==NULL) return -1;
LONG lRowLen = (lWidth*nBitCount + 31) / 32*4;
BYTE* pSrc;
BYTE* pTrace;
LONG i;
LONG j;
LONG lGirth = 0;
BYTE bPixel;
BOOL bFindStartPoint; //是否找到起始点
BOOL bFindPoint; //是否扫描到一个边界点
Point StartPoint,CurrentPoint;//起始边界点与当前边界点
int Direction[8][2]={{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1},{-1,0}};//八个方向和起始扫描方向
int BeginDirect;
if(nBitCount == 8)
{
//int nDirectOld=0;拐点统计
//int nSub;
memset(pTraceBits, 255, lRowLen * lHeight);
bFindStartPoint = FALSE; //先找到最左上方的边界点
for (j=rcTrans.top;(j<rcTrans.bottom&& !bFindStartPoint);j++)
{
for(i=rcTrans.left;(i<rcTrans.right && !bFindStartPoint);i++)
{
pSrc = pSrcBits + lRowLen * j + i;
bPixel = *pSrc;

if(bPixel == Value)
{
bFindStartPoint = TRUE;
StartPoint.Height = j;
StartPoint.Width = i;
pTrace = pTraceBits + lRowLen * j + i;
*pTrace = (unsigned char)0;
}
}
}

if(!bFindStartPoint) return FALSE; //起点
BeginDirect = 0;
bFindStartPoint = FALSE;
CurrentPoint.Height = StartPoint.Height;
CurrentPoint.Width = StartPoint.Width;
int xOffset;
int yOffset;
while(!bFindStartPoint)
{
bFindPoint = FALSE;
while(!bFindPoint)
{
xOffset = (CurrentPoint.Width + Direction[BeginDirect][0]);
yOffset = (CurrentPoint.Height + Direction[BeginDirect][1]);
if(xOffset>=rcTrans.left && xOffset<rcTrans.right && yOffset>=rcTrans.top && yOffset<rcTrans.bottom)
{
pSrc = pSrcBits + lRowLen * yOffset + xOffset;
bPixel = *pSrc;
if(bPixel == Value)
{
bFindPoint = TRUE;
CurrentPoint.Height = CurrentPoint.Height + Direction[BeginDirect][1];
CurrentPoint.Width = CurrentPoint.Width + Direction[BeginDirect][0];
if(CurrentPoint.Height == StartPoint.Height && CurrentPoint.Width == StartPoint.Width)
{
bFindStartPoint = TRUE;
}
pTrace = pTraceBits + lRowLen * CurrentPoint.Height + CurrentPoint.Width;
*pTrace = Value;
lGirth++;
/*nSub = abs(BeginDirect - nDirectOld); 拐点统计
nSub = nSub>4?8-nSub:nSub;
if(nSub > 1)
{
if(BeginDirect%2 == 0)
nDirectOld = BeginDirect;
else
{
if((BeginDirect-nDirectOld+8)%8 == 5)
{
nDirectOld = (nDirectOld+6)%8;
}
else
{
nDirectOld = (nDirectOld+2)%8;
}
}
pTraceBits[yOffset][xOffset] = 254;
}*/
//扫描的方向逆时针旋转两格
BeginDirect--;
if(BeginDirect == -1) BeginDirect = 7;
BeginDirect--;
if(BeginDirect == -1) BeginDirect = 7;
}
wrcluomo 2004-07-29
  • 打赏
  • 举报
回复
图上有多个你把处理过的这个赋值为254再找别的.
hyw1980 2004-07-29
  • 打赏
  • 举报
回复
TO rabbithao:
你好!我看过你的代码,而且我之前还试过,对于只有一个物体的图像是可行的,如果图上又很多个无规律的轮廓就只能找出一个。我试过在外层加循环,总是跳不出来。可能是我程序上的问题吧!
我在网上搜索,好像很少有这方面的代码啊。能不能推荐几个站点?
hyw1980 2004-07-28
  • 打赏
  • 举报
回复
我在一本数字图像处理书上找到过相关的代码,竟然也不行!

各位做过链码的不管是几链码,能不能贴一个上来或者发到我的邮箱tigerhoo88@sohu.com

我学习学习,开拓一下思路。谢谢!
rabithao 2004-07-28
  • 打赏
  • 举报
回复
你上面的代码是做连吗跟踪的边缘检测,
代码如下:
bool FindStartPoint; //whether find a start point ;
bool FindPoint; //whether find a border point ;
CPoint StartPoint, CurrentPoint;
int startDirect;
int Goto[8][2] = { {-1, -1}, {0, -1}, {1, -1}, {1, 0}, {1, 1}, {0, 1}, {-1, 1},{-1, 0} };
int lwidthbyte = (biWidth + 3) / 4 * 4;
unsigned char* temp = ( unsigned char* )malloc( lwidthbyte * biHeight );
memset( temp, 255, lwidthbyte * biHeight );
FindStartPoint = false;
for( i = 0; i < biHeight; i++ )
{
for( j = 0; j < biWidth; j++ )
{
if( *( pBitmapData + lWidthByte * i + j * 3) == 0 )
{
FindStartPoint = true;
StartPoint.x = i;
StartPoint.y = j;
*( temp + lwidthbyte * i + j) = 0;
}
if(FindStartPoint)
break;
}
if( FindStartPoint )
break;
}
startDirect = 0;
FindStartPoint = false;
CurrentPoint.x = StartPoint.x;
CurrentPoint.y = StartPoint.y;
while( !FindStartPoint )
{
FindPoint = false;
while( !FindPoint )
{
if( *(pBitmapData + lWidthByte * ( CurrentPoint.x + Goto[startDirect][1]) + ( CurrentPoint.y + Goto[startDirect][0]) * 3) == 0 )
{
FindPoint = true;
CurrentPoint.x = CurrentPoint.x + Goto[startDirect][1];
CurrentPoint.y = CurrentPoint.y + Goto[startDirect][0];
if( CurrentPoint.x == StartPoint.x && CurrentPoint.y == StartPoint.y )
{
FindStartPoint = true;
}
*( temp + lwidthbyte * CurrentPoint.x + CurrentPoint.y ) = 0;
startDirect--;
if( startDirect == -1)
{
startDirect = 7;
}
startDirect--;
if( startDirect == -1)
{
startDirect = 7;
}
}
else
{
startDirect++;
if(startDirect == 8)
{
startDirect = 0;
}
}
}
}
for( i = 0; i < biHeight; i++ )
{
for( j = 0; j < biWidth; j++ )
{
*( pBitmapData + lWidthByte * i + j * 3 ) = *( temp + lwidthbyte* i + j );
*( pBitmapData + lWidthByte * i + j * 3 + 1 ) = *( temp + lwidthbyte* i + j );
*( pBitmapData + lWidthByte * i + j * 3 + 2 ) = *( temp + lwidthbyte* i + j );
}
}
free( temp );
rabithao 2004-07-28
  • 打赏
  • 举报
回复
我这儿也有这本书的,书上的代码是可以的:
(24位图)按照灰度方法处理的
unsigned char* pBitmap = m_Bitmap;
LPBITMAPINFO lpBitmapInfo = ( LPBITMAPINFO )( pBitmap + 14);
unsigned char* pBitmapData = pBitmap + ( (LPBITMAPFILEHEADER)pBitmap)->bfOffBits;
int biWidth = ( (LPBITMAPINFOHEADER)lpBitmapInfo )->biWidth;
int biHeight = ( (LPBITMAPINFOHEADER)lpBitmapInfo )->biHeight;
int lWidthByte = ( biWidth * 3 + 3 ) / 4 * 4;
int i, j;

x_sign = 0;
m_temp = 0;
x_temp = 0;
y_temp = 0;
for( i = 0; i < 255; i++ )
{
flag[i] = 0;
}
int lwidthbyte = ( biWidth + 3 ) / 4 * 4;
p_temp = (unsigned char*)malloc( lwidthbyte * biHeight );
memset( p_temp, 255, lwidthbyte * biHeight );
for( i = 1; i < biHeight - 1; i++ )
{
for( j = 1; j < biWidth - 1; j++ )
{
//if the current point is the black pixel
if( *(pBitmapData + lWidthByte * (biHeight - i - 1) + j * 3) == 0 )
{
//if the right-top is the blcak point
if( *(pBitmapData + lWidthByte * (biHeight - i - 1 + 1) + (j + 1) * 3) == 0 )
{
*( p_temp + lwidthbyte * (biHeight - 1 - i) + j ) = *( p_temp + lwidthbyte * (biHeight - 1 - i + 1) + j + 1 ) ;
x_temp = *( p_temp + lwidthbyte * (biHeight - 1 - i + 1) + j + 1);
flag[x_temp] += 1;
//left pixel
if( *(pBitmapData+ lWidthByte * (biHeight - 1 - i) + (j - 1) * 3) == 0 && *(p_temp + lwidthbyte * (biHeight - 1 - i) + j - 1 ) != x_temp )
{
y_temp = *( p_temp + lwidthbyte * (biHeight - i - 1 ) + j - 1 );
for( int m = 0; m < biHeight; m++ )
{
for( int n = 0; n < biWidth; n++ )
{
if( *(p_temp + lwidthbyte * (biHeight - m - 1) + n ) == y_temp )
{
flag[y_temp] = 0;
*(p_temp + lwidthbyte * (biHeight - m - 1) + n) = x_temp;
flag[x_temp] += 1;
}
}
}
}
//left-top
if( *(pBitmapData+ lWidthByte * (biHeight - 1 - i + 1) + (j - 1) * 3) == 0 && *(p_temp + lwidthbyte * (biHeight - 1 - i + 1) + j - 1) != x_temp )
{
y_temp = *( p_temp + lwidthbyte * (biHeight - i - 1 + 1 ) + j - 1 );
for( int m = 0; m < biHeight; m++ )
{
for( int n = 0; n < biWidth; n++ )
{
if( *(p_temp + lwidthbyte * (biHeight - m - 1) + n ) == y_temp )
{
flag[y_temp] = 0;
*(p_temp + lwidthbyte * (biHeight - m - 1) + n) = x_temp;
flag[x_temp] += 1;
}
}
}
}
}
//top
else if( *(pBitmapData + lWidthByte * (biHeight - 1 - i + 1) + j * 3) == 0 )
{
*( p_temp + lwidthbyte * (biHeight - 1 - i) + j ) = *( p_temp + lwidthbyte * (biHeight - 1 - i + 1) + j ) ;
x_temp = *( p_temp + lwidthbyte * (biHeight - 1 - i + 1) + j );
flag[x_temp] += 1;
}
//left-top
else if( *(pBitmapData + lWidthByte * (biHeight - 1 - i + 1) + (j - 1) * 3) == 0 )
{
*( p_temp + lwidthbyte * (biHeight - 1 - i) + j ) = *( p_temp + lwidthbyte * (biHeight - 1 - i + 1) + j - 1 ) ;
x_temp = *( p_temp + lwidthbyte * (biHeight - 1 - i + 1) + j - 1 );
flag[x_temp] += 1;
}
//left
else if( *(pBitmapData + lWidthByte * (biHeight - 1 - i) + (j - 1) * 3) == 0 )
{
*( p_temp + lwidthbyte * (biHeight - 1 - i) + j ) = *( p_temp + lwidthbyte * (biHeight - 1 - i) + j - 1 ) ;
x_temp = *( p_temp + lwidthbyte * (biHeight - 1 - i) + j - 1 );
flag[x_temp] += 1;
}
else
{
x_sign++;
m_temp = x_sign;
*(p_temp + lwidthbyte * (biHeight - 1 - i) + j ) = m_temp;
flag[m_temp] = 1;
}
}
}
}
酒红绿叶 2004-07-28
  • 打赏
  • 举报
回复
首先应该注意到图像的问题,,
遍历的点是黑还是白,,
是否有离散的点,等等,,,,
hyw1980 2004-07-28
  • 打赏
  • 举报
回复
除了链码,其他的方法也可以呀,请各位高手指点迷津。
wqs6 2004-07-27
  • 打赏
  • 举报
回复
8链码我觉得 挺好用的!

不是很难,可能是什么地方的 小错误

我曾经编过,但是我现在不在学校

你自己找找吧!
hyw1980 2004-07-27
  • 打赏
  • 举报
回复
to:weiym
帮我看看,先谢谢了!
hyw1980 2004-07-27
  • 打赏
  • 举报
回复
我是第一次在这里提问,没注意到给分,分数再加。

思路大概是:
1,定义8链码,方向是与0,45,90,135,...依次对应;
2,搜寻二值图上目标区域,找到起始点;
3,从起始点开始,用链码找区域点,找过的点改变其值,以便不再重复;每找一个点,area[]++,计算面积。
4,当该区域所有的点都搜到之后,结束,继续找下一个起始点。
遇到的问题在第三步,好像是循环。但是我不知道再怎么修改?
请高手帮忙看看?
weiym 2004-07-27
  • 打赏
  • 举报
回复
好长的代码,你还是说一下思路
别人可以大致看一下
【资源说明】 1.项目代码均经过功能验证ok,确保稳定可靠运行。欢迎下载食用体验! 2.主要针对各个计算机相关专业,包括计算机科学、信息安全、数据科学与大数据技术、人工智能、通信、物联网等领域的在校学生、专业教师、企业员工。 3.项目具有丰富的拓展空间,不仅可作为入门进阶,也可直接作为毕设、课程设计、大作业、初期项目立项演示等用途。 4.当然也鼓励大家基于此进行二次开发。在使用过程中,如有问题或建议,请及时沟通。 5.期待你能在项目中找到乐趣和灵感,也欢迎你的分享和反馈! 【项目介绍】 基于图像处理的水果识别系统matlab完整源码+报告+答辩PPT+详细注释+说明文档.zip 一、设计方案 在计算机中,图像由像素逐点描述,每个像素点都有一个明确的位置和色彩数值。使用 Matlab 软件读取图像,以矩阵形式存放图像数据,其扫描规则是从左向右,从上到下。 对于一副水果图像为了处理方便,我们首先要把彩色图像转化为灰度图像。然后对图像进行二值化处理来获得每个水果的区域特征。 在水果与背景接触处二值化会导致图像边缘部分有断裂,毛躁的部分。所以采用边缘提取以弥补断裂的边缘部分,然后基于数学形态算子对图像进行去除断边,图像填充等必要的后续处理。经过图像分割后,水果和背景很明显地被区分开来,然后需要对每种水果的特征进行提取。 先对图像进行标签化,所谓图像的标签化是指对图像中互相连通的所有像素赋予同样的标号。经过标签化处理就能把各个连通区域进行分离,从而可以研究它们的特征。 二、关键技术 (一)图像二值化 # 1、灰度化 % 将真彩色图像 i 转化为灰度图像 I I=rgb2gray(i); 在 RGB 模型中,如果 R=G=B 时,则彩色表示一种灰度颜色,其中 R=G=B 的值叫灰度值,因此,灰度图像每个像素只需一个字节存放灰度值(又称强度值、亮度值),灰度范围为0-255。 # 2、二值化 % level 为阈(yu) 值,取值从0到1. % 本项目考虑到图片背景颜色为白色,亮度较大,因此选取 `level=0.9` 来实现二值化。 I=im2bw(i,level) 一幅图像包含目标物体、背景还有噪声,要想从多值的数字图像中直接提取出目标物体,最经常使用的方法就是设定一个全局的阈值 T,用 T 将图像的数据分成两部分:大于 T 的像素群和小于 T 的像素群。将大于 T 的像素群的像素值设定为白色(或者黑色),小于 T 的像素群的像素值设定为黑色(或者白色)。 比方:计算每个像素的(R+G+B)/3,假设>127,则设置该像素为白色,即R=G=B=255;否则设置为黑色,即R=G=B=0。 二)边缘提取 # 1、开运算 I=imopen(i,SE); 先腐蚀后膨胀的过程称为开运算。(看上去把细微连在一起的两块目标分开了) 开运算作用:可以使边界平滑,消除细小的尖刺,断开窄小的连接,保持面积大小不变等。 I=imerode(i,SE); 腐蚀运算作用:消除物体边界点,使边界点向内部收缩,可以把小于结构元素的物体去除。 膨胀的作用:将与物体接触的所有背景点合并到物体中,是目标增大,可填补目标中的空洞。 # 2、数学形态学运算 % bwmorph 函数是对图像进行指定的形态学操作。 % ‘remove’即代表如果一个像素点的4邻域都为1, 则该像素点将被置0;该选项将导致边界像素上的1被保留下来。 I=bwmorph(i,'remove'); 提取图像种水果的边界用于标记各个区域
【资源说明】 1、该资源包括项目的全部源码,下载可以直接使用! 2、本项目适合作为计算机、数学、电子信息等专业的课程设计、期末大作业和毕设项目,作为参考资料学习借鉴。 3、本资源作为“参考资料”如果需要实现其他功能,需要能看懂代码,并且热爱钻研,自行调试。 Python基于深度学习的矿车装载状态计数系统(源码+项目说明).zip ## 1.研究背景与意义 随着科技的不断发展,深度学习在各个领域中得到了广泛的应用。其中,计算机视觉是深度学习的一个重要应用领域。计算机视觉可以通过对图像或视频的处理和分析,实现对图像中物体的识别、分类、定位等任务。在工业领域中,计算机视觉的应用可以提高生产效率、降低成本、提高产品质量等。 矿车装载状态计数系统是一个在矿山行业中非常重要的应用。在矿山中,矿车是用来运输矿石或其他物料的重要工具。矿车的装载状态对于矿山的生产效率和成本控制有着重要的影响。因此,开发一种能够准确、快速地检测和计数矿车装载状态的系统对于矿山行业具有重要的意义。 传统的矿车装载状态计数方法主要依赖于人工的视觉检测和计数,这种方法存在着许多问题。首先,人工检测和计数需要大量的人力资源,成本较高。其次,人工检测和计数容易受到环境条件、光照条件等因素的影响,导致检测和计数的准确性不高。此外,人工检测和计数速度较慢,无法满足矿山行业对于高效生产的需。 基于深度学习的计算机视觉方法可以有效地解决传统方法存在的问题。深度学习可以通过对大量数据的学习和训练,自动学习到图像中的特征和模式,并实现对图像的自动处理和分析。因此,基于深度学习的矿车装载状态计数系统可以实现对矿车装载状态的自动检测和计数,提高检测和计数的准确性和速度。 Python作为一种简单易学、功能强大的编程语言,被广泛应用于深度学习领域。Python提供了许多强大的深度学习框架和工具,如TensorFlow、PyTorch等,可以帮助开发者快速搭建和训练深度学习模型。因此,使用Python开发基于深度学习的矿车装载状态计数系统具有较高的可行性和便利性。 本研究的目标是基于深度学习技术,开发一种Python实现的矿车装载状态计数系统,并提供相应的部署教程和源码。该系统可以实现对矿车装载状态的自动检测和计数,提高检测和计数的准确性和速度。通过提供部署教程和源码,可以帮助其他研究者和开发者快速理解和应用该系统,推动矿山行业的智能化和自动化发展。 总之,基于深度学习的矿车装载状态计数系统具有重要的应用价值和研究意义。通过该系统的开发和应用,可以提高矿山行业的生产效率和成本控制,推动矿山行业的智能化和自动化发展。同时,通过提供部署教程和源码,可以促进深度学习技术在计算机视觉领域的应用和推广。 # 2.图片演示 ![2.png](8c884499481dce8f317395b9787a68f7.webp) ![3.png](b3f59c45ddb6e0b03839a2258fe2eb1c.webp) ![4.png](918ff9255b89953e62fd402d0c37cefc.webp) # 3.视频演示 [Python基于深度学习的装载状态矿车统计系统(部署教程和源码)_哔哩哔哩_bilibili](https://www.bilibili.com/video/BV1V8411Q7Ww/?vd_source=ff015de2d29cbe2a9cdbfa7064407a08) # 4.车辆装载状态的判别 以运输车前进的方向为正方向,在运输车的货物图像上建立坐标系,通过 Canny 边缘检测算法与 So-bel 算法来计算图像灰度的近似梯度,获取车辆侧面外露货物的外形曲线图,并对此建立平面直角坐标系,如图所示。 ![image.png](f58fc409a4b3e781e713f6b5359c5b89.webp) 由于货物形状具有不规则性,本文得到在坐标系中货物的大概位置后,以矿车水平及竖直尺寸为依据,使用高斯滤波算法对其去除噪声,使不规则曲线转换成平滑曲线,结果如图所示。 ![image.png](ddc6d675922f7dee11a193674a077ac1.webp) 以像素点作为单位,计算车辆货物的满额率。 其中,货物的面积为经过滤波后的平滑曲线与坐标系的x、y 轴所围成区域面积,前板总成的水平延长线与x、y 轴形成的闭合区域面积为满额面积,即图 中虚线与 x、y 轴所围成区域面积。 满额率的计算公式为: ![image.png](250bce773a9b0218acaaf74ea64eb4a3.webp) ## 5.核心代码讲解 #### 5.1 detector_CPU.py 下面是封装为类后的代码: ```python c

19,468

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧