📄 imageprocess.c
字号:
//*************************************************************************
//* *
//* *************************图像处理函数*********************** *
//* *
//*************************************************************************
#include "includes.h"
//*************************************************************************
//* *
//* ***********************图像二值化分割********************** *
//* *
//*************************************************************************
//通过阈值比较对图像进行二值化分割。
void vImageDivide(void)
{
unsigned char ucRow,ucColumn;
unsigned char *pucTemp;
for(ucColumn=COLUMN_MIN;ucColumn<COLUMN_MAX;ucColumn++)
{
for(ucRow=ROW_MIN;ucRow<ROW_MAX;ucRow++)
{
pucTemp=puca_BufferProcess+ucRow*IMAGE_COLUMN+ucColumn;
if(*pucTemp<2)
*pucTemp=BLACK_POINT;
else
*pucTemp=WHITE_POINT;
}
}
}
//*************************************************************************
//* *
//* ***************************图像运算************************ *
//* *
//*************************************************************************
//通过腐蚀膨胀运算滤除噪声,提取出图像的基本特征。
void vImageCalculate(void)
{
unsigned char ucRow,ucColumn;
unsigned char *pucTemp;
//*************************************************************************
//膨胀运算,对于每一列,如果一个白点的两侧为黑点则认为改点为黑点。
for(ucColumn=COLUMN_MIN;ucColumn<COLUMN_MAX;ucColumn++)
{
for(ucRow=ROW_MIN+1;ucRow<ROW_MAX-3;ucRow++)
{
pucTemp=puca_BufferProcess+ucRow*IMAGE_COLUMN+ucColumn;
if(*pucTemp==WHITE_POINT)
{
if((*(pucTemp-IMAGE_COLUMN)==BLACK_POINT)
&&(*(pucTemp+IMAGE_COLUMN)==BLACK_POINT))
{
*pucTemp=BLACK_POINT;
ucRow++;
}
}
}
}
//*************************************************************************
//腐蚀运算,对于每一列,如果一个黑点的两侧为白点则认为改点为白点。
for(ucColumn=COLUMN_MIN;ucColumn<COLUMN_MAX;ucColumn++)
{
for(ucRow=ROW_MIN+1;ucRow<ROW_MAX-3;ucRow++)
{
pucTemp=puca_BufferProcess+ucRow*IMAGE_COLUMN+ucColumn;
if(*pucTemp==BLACK_POINT)
{
if((*(pucTemp-IMAGE_COLUMN)==WHITE_POINT)
&&(*(pucTemp+IMAGE_COLUMN)==WHITE_POINT))
{
*pucTemp=WHITE_POINT;
ucRow++;
}
}
}
}
}
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#define VIDEO_CENTER 42 //摄像头中心位置参考
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
signed char sc_CenterEx=0; //黑线中心坐标偏移
signed char sc_CenterExLast=0;
signed char sc_NearEx=0; //黑线中心坐标偏移
signed char sc_NearExLast=0;
signed char sc_FarEx=0; //黑线中心坐标偏移
signed char sc_FarExLast=0;
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//检测结果正误标志,如果为零则正确,如果大于零则错误。
unsigned char uc_ErrorFlag=CORRECT;
//************************************************************************
//* *
//* ********************计算中心线坐标************************ *
//* *
//************************************************************************
void vGetCenter(void)
{
unsigned char ucRow,ucColumn,ucCount;
unsigned char *pucTemp;
unsigned int uiSum;
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//远处黑线坐标中心值。
uiSum=0;
ucCount=0;
for(ucColumn=COLUMN_MIN;ucColumn<COLUMN_MAX-8;ucColumn++)
{
for(ucRow=ROW_MIN;ucRow<ROW_MAX;ucRow++)
{
pucTemp=puca_BufferProcess+ucRow*IMAGE_COLUMN+ucColumn;
if(*pucTemp==BLACK_POINT)
{
uiSum+=ucRow;
ucCount++;
}
}
}
if(ucCount>12)
{
sc_FarEx=(unsigned char)(uiSum/ucCount)-VIDEO_CENTER;
if((sc_FarEx-sc_FarExLast)<25&&(sc_FarEx-sc_FarExLast)>-25)
sc_FarExLast=sc_FarEx;
else
sc_FarEx=sc_FarExLast;
}
else
sc_FarEx=sc_FarExLast;
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//中间黑线坐标中心值。
uiSum=0;
ucCount=0;
for(ucColumn=COLUMN_MIN+3;ucColumn<COLUMN_MAX-5;ucColumn++)
{
for(ucRow=ROW_MIN;ucRow<ROW_MAX;ucRow++)
{
pucTemp=puca_BufferProcess+ucRow*IMAGE_COLUMN+ucColumn;
if(*pucTemp==BLACK_POINT)
{
uiSum+=ucRow;
ucCount++;
}
}
}
if(ucCount>12)
{
sc_CenterEx=(unsigned char)(uiSum/ucCount)-VIDEO_CENTER;
if((sc_CenterEx-sc_CenterExLast)<25&&(sc_CenterEx-sc_CenterExLast)>-25)
sc_CenterExLast=sc_CenterEx;
else
sc_CenterEx=sc_CenterExLast;
}
else
sc_CenterEx=sc_CenterExLast;
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//近处黑线坐标中心值。
uiSum=0;
ucCount=0;
for(ucColumn=COLUMN_MIN+8;ucColumn<COLUMN_MAX;ucColumn++)
{
for(ucRow=ROW_MIN;ucRow<ROW_MAX;ucRow++)
{
pucTemp=puca_BufferProcess+ucRow*IMAGE_COLUMN+ucColumn;
if(*pucTemp==BLACK_POINT)
{
uiSum+=ucRow;
ucCount++;
}
}
}
if(ucCount>12)
{
sc_NearEx=(unsigned char)(uiSum/ucCount)-VIDEO_CENTER;
if((sc_NearEx-sc_NearExLast)<25&&(sc_NearEx-sc_NearExLast)>-25)
sc_NearExLast=sc_NearEx;
else
sc_NearEx=sc_NearExLast;
}
else
sc_NearEx=sc_NearExLast;
// sc_CenterEx=(signed char)((sc_CenterEx+sc_FarEx+sc_NearEx)/3);
}
//*************************************************************************
//* *
//* **********************图像处理主函数*********************** *
//* *
//*************************************************************************
void vImageProcess(void)
{
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<图像二值化分割>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//通过阈值比较对图像进行二值化分割。
vImageDivide();
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<图像运算>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//滤除噪声。
vImageCalculate();
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<计算黑点区域>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//根据二值化后的图像,从中分辨出正确的黑线,交叉线和起跑线。
// vGetDomain();
//<<<<<<<<<<<<<<<<<<<<<<<<<<<计算中心线坐标>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//根据二值化后的图像数据计算中心线位置。
vGetCenter();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -