使用原子的ov7670代码,用mini的板子做图像二值化,边缘检测,每次只要检测到就卡屏,求助问题在哪里
//////////////////////////////////////////////////////////////////////////////////////////////就加了这些,别的都没改,效果如图
GPIOB->CRL=0X33333333;
if(color<25000)
{
color=0x0000;
m=j%320;
n=j/320;
if(i==0)
{
x
=m;
y=n;
Xmin=m;
Xmax=m;
Ymin=n;
Ymax=n;
i++;
}
x=m;
y=n;
if((x-x[i-1])<50&&(y-y[i-1])<50)
{
if((x<315)&&(x>5)&&(y<235)&&(y>5))
{
if(x>Xmax)
Xmax=x;
if(x<Xmin)
Xmin=x;
if(y>Ymax)
Ymax=y;
if(y<Ymin)
Ymin=y;
i++;
}
}
}
else
color=0xFFFF;
LCD_WR_DATA(color);
}
POINT_COLOR=RED;
LCD_DrawRectangle(Xmin,Ymin,Xmax,Ymax);
OV7670_CS=1;
OV7670_RCK=0;
是数组越界了,请问你有好的相关的算法可以开源看一下吗?换了好几种思路都不能实现
#include "bsp_led.h"
#include "bsp_usart.h"
#include "bsp_ili9341_lcd.h"
#include "bsp_spi_flash.h"
#include "bsp_sccb.h"
#include "ov7725.h"
#include "ColorTracer.h"
/**
* @brief Ö÷oˉêy
* @param ÎT
* @retval ÎT
*/
int main(void)
{
//uint8_t status;
LED_GPIO_Config();
LED_BLUE;
USART_Config();
SPI_FLASH_Init();
ILI9341_Init(); //LCD 3õê¼»ˉ
ILI9341_GramScan( 2 ); //óòϽÇ->×óéϽÇ
ILI9341_Clear(0,0,320,240,macBLACK);//ÇåÆᣬÏÔê¾è«oú
// SCCB_GPIO_Config();
// status = OV7725_Init();
// printf("%d ",status);
OV7725_GPIO_Config();
while( OV7725_Init() != SUCCESS );
Ov7725_Vsync = 0;
while ( 1 )
{
if( Ov7725_Vsync == 2 )
{
Ov7725_Vsync = 0;
if(Trace(&condition, &result))
{
ILI9341_DrawRectangle ( result.x-result.w/2, result.y-result.h/2, result.w, result.h, macRED, 0 );
ILI9341_DrawRectangle ( result.x-2, result.y-2, 4, 4, macRED, 1 );
}
}
}
/* add your code here ^_^. */
}
/*********************************************END OF FILE**********************/
#include "ColorTracer.h"
#include "bsp_ili9341_lcd.h"
RESULT result;
//TARGET_CONDITION condition={50,80,20,250,20,200,40,40,320,240};
//궱eμÄêÇÂìé«
TARGET_CONDITION condition={
60, //Ä¿±ê×îD¡é«¶è£¬H_MIN
110, //Ä¿±ê×î′ó髶裬H_MAX
50, //Ä¿±ê×îD¡±¥oí¶è£¬S_MIN
240, //Ä¿±ê×î′ó±¥oí¶è£¬S_MAX
60, //Ä¿±ê×îD¡áá¶è£¬L_MIN
190, //Ä¿±ê×î′óáá¶è£¬L_MAX
40, //Ä¿±ê×îD¡¿í¶è£¬WIDTH_MIN
40, //Ä¿±ê×îD¡¸ß¶è£¬HEIGHT_MIN
320, //Ä¿±ê×î′ó¿í¶è£¬WIDTH_MAX
240 //Ä¿±ê×î′ó¸ß¶è£¬HEIGHT_MAX
};
//2aêÔÎTÎó
#define minOf3Values( v1, v2, v3 ) ( (v1<v2) ? ( (v1<v3) ? (v1) : (v3) )
: ( (v2<v3) ? (v2) : (v3) ) )
#define maxOf3Values( v1, v2, v3 ) ( (v1>v2) ? ( (v1>v3) ? (v1) : (v3) )
: ( (v2>v3) ? (v2) : (v3) ) )
typedef struct //RGB
{
unsigned char Red; // [0,255]
unsigned char Green; // [0,255]
unsigned char Blue; // [0,255]
}COLOR_RGB;
typedef struct //HLSÑÕé«
{
unsigned char Hue; //髶è ,[0,240]
unsigned char Lightness; //áá¶è,[0,240]
unsigned char Saturation; //±¥oí¶è,[0,240]
}COLOR_HLS;
typedef struct //ËÑÑ°Çøóò
{
unsigned int X_Start;
unsigned int X_End;
unsigned int Y_Start;
unsigned int Y_End;
}SEARCH_AREA;
/**
* @brief »ñè¡ ILI9341 ÏÔê¾Æ÷éÏÄ3ò»¸ö×ø±êμãμÄÏñËØêy¾Y
* @param usX £oÔúìض¨é¨Ãè·½ÏòϸÃμãμÄX×ø±ê
* @param usY £oÔúìض¨é¨Ãè·½ÏòϸÃμãμÄY×ø±ê
* @retval ÏñËØêy¾Y
*/
//uint16_t ILI9341_GetPointPixel( uint16_t usX, uint16_t usY )
#define getRGBColor_16bits ILI9341_GetPointPixel
/**
* @brief ¶áè¡Ä3ò»μãÑÕé«êy¾Y
* @param usX £o¸ÃμãμÄX×ø±ê
* @param usY £o¸ÃμãμÄY×ø±ê
* @param color_rgb £oCOLOR_RGB½á11ì壬′æ′¢ÑÕé«êy¾Y
* @retval ÎT
*/
static void ReadColor( uint16_t usX, uint16_t usY, COLOR_RGB* color_rgb )
{
unsigned short rgb;
rgb = getRGBColor_16bits( usX, usY ); //»ñè¡ÑÕé«êy¾Y
//×a»»3éÖμóòÎa[0,255]μÄèyÔ-é«Öμ
color_rgb->Red = (unsigned char)( ( rgb & 0xF800 ) >> 8 );
color_rgb->Green = (unsigned char)( ( rgb & 0x07E0 ) >> 3 );
color_rgb->Blue = (unsigned char)( ( rgb & 0x001F ) << 3 );
//color_rgb->Blue = (unsigned char)( ( rgb & 0x001F ) );
}
/**
* @brief RGB×aHLS
* @param color_rgb £oCOLOR_RGB½á11ì壬′æ′¢RGB¸ñê½ÑÕé«êy¾Y
* @param color_hls £oCOLOR_HLS½á11ì壬′æ′¢HLS¸ñê½ÑÕé«êy¾Y
* @retval ÎT
*/
static void RGB2HSL( const COLOR_RGB* color_rgb, COLOR_HLS* color_hls )
{
int r, g, b;
int h, l, s;
int max, min, dif;
r = color_rgb->Red;
g = color_rgb->Green;
b = color_rgb->Blue;
max = maxOf3Values( r, g, b );
min = minOf3Values( r, g, b );
dif = max - min;
//¼ÆËãl£¬áá¶è
l = ( max + min ) * 240 / 255 / 2;
//¼ÆËãh£¬é«¶è
if( max == min )//ÎT¶¨òå
{
s = 0;
h = 0;
}
else
{
//¼ÆËã髶è
if( max == r )
{
if( min == b )//h½éóú0μ½40
{
h = 40 * ( g - b ) / dif;
}
else if( min == g )//h½éóú200μ½240
{
h = 40 * ( g - b ) / dif + 240;
}
}
else if( max == g )
{
h = 40 * ( b - r ) / dif + 80;
}
else if( max == b )
{
h = 40 * ( r - g ) / dif + 160;
}
//¼ÆËã±¥oí¶è
if( l == 0 )
{
s = 0;
}
else if( l <= 120 )
{
s = dif * 240 / ( max + min );
}
else
{
s = dif * 240 / ( 480 - ( max + min ) );
}
}
color_hls->Hue = h; //髶è
color_hls->Lightness = l; //áá¶è
color_hls->Saturation = s; //±¥oí¶è
}
/**
* @brief ÑÕé«Æ¥Åä
* @param color_hls £oCOLOR_HLS½á11ì壬′æ′¢HLS¸ñê½ÑÕé«êy¾Y
* @param condition £oTARGET_CONDITION½á11ì壬′æ·ÅÏ£íûμÄÑÕé«êy¾YãDÖμ
* @retval 1£oÏñËØμãÑÕé«ÔúÄ¿±ê·¶Î§Äú£»0£oÏñËØμãÑÕé«2»ÔúÄ¿±ê·¶Î§Äú¡£
*/
static int ColorMatch(const COLOR_HLS* color_hls, const TARGET_CONDITION* condition )
{
if(
color_hls->Hue > condition->H_MIN &&
color_hls->Hue < condition->H_MAX &&
color_hls->Lightness > condition->L_MIN &&
color_hls->Lightness < condition->L_MAX &&
color_hls->Saturation > condition->S_MIN &&
color_hls->Saturation < condition->S_MAX
)
return 1;
else
return 0;
}
/**
* @brief Ñ°Õò¸ˉê′ÖDDÄ
* @param x £o¸ˉê′ÖDDÄx×ø±ê
* @param y £o¸ˉê′ÖDDÄy×ø±ê
* @param condition £oTARGET_CONDITION½á11ì壬′æ·ÅÏ£íûμÄÑÕé«êy¾YãDÖμ
* @param area £oSEARCH_AREA½á11ì壬2éÕò¸ˉê′ÖDDÄμÄÇøóò
* @retval 1£oÕòμ½á˸ˉê′ÖDDÄ£¬x¡¢yÎa¸ˉê′ÖDDÄμÄ×ø±ê£»0£oûóDÕòμ½¸ˉê′ÖDDÄ¡£
*/
static int SearchCenter(unsigned int* x, unsigned int* y, const TARGET_CONDITION* condition, SEARCH_AREA* area )
{
unsigned int i, j, k;
unsigned int FailCount=0;
unsigned int SpaceX, SpaceY;
COLOR_RGB rgb;
COLOR_HLS hls;
SpaceX = condition->WIDTH_MIN / 3;
SpaceY = condition->HEIGHT_MIN / 3;
for(i=area->Y_Start; i<area->Y_End; i+=SpaceY)
{
for(j=area->X_Start; j<area->X_End; j+=SpaceX)
{
FailCount = 0;
for(k=0; k<SpaceX+SpaceY; k++)
{
if(k<SpaceX)
ReadColor( j+k, i+SpaceY/2, &rgb );
else
ReadColor( j+SpaceX/2, i+k-SpaceX, &rgb );
RGB2HSL( &rgb, &hls );
if(!ColorMatch( &hls, condition ))
FailCount++;
if(FailCount>( (SpaceX+SpaceY) >> ALLOW_FAIL_PER ))
break;
}
if(k == SpaceX+SpaceY)
{
*x = j + SpaceX / 2;
*y = i + SpaceY / 2;
return 1;
}
}
}
return 0;
}
/**
* @brief ′ó¸ˉê′ÖDDÄÏòía¸ˉê′£¬μÃμ½DÂμĸˉê′ÖDDÄ
* @param oldX £oÏèÇ°μĸˉê′ÖDDÄx×ø±ê
* @param oldX £oÏèÇ°μĸˉê′ÖDDÄy×ø±ê
* @param condition £oTARGET_CONDITION½á11ì壬′æ·ÅÏ£íûμÄÑÕé«êy¾YãDÖμ
* @param result £oRESULT½á11ì壬′æ·Å¼ì2a½á1û
* @retval 1£o¼ì2a3é1|£»0£o¼ì2a꧰ü¡£
*/
static int Corrode(unsigned int oldX, unsigned int oldY, const TARGET_CONDITION* condition, RESULT* result )
{
unsigned int Xmin, Xmax, Ymin, Ymax;
unsigned int i;
unsigned int FailCount=0;
COLOR_RGB rgb;
COLOR_HLS hls;
for(i=oldX; i>IMG_X; i--)
{
ReadColor(i, oldY, &rgb);
RGB2HSL(&rgb, &hls);
if(!ColorMatch(&hls, condition))
FailCount++;
if(FailCount>(((condition->WIDTH_MIN+condition->WIDTH_MAX)>>2)>>ALLOW_FAIL_PER))
break;
}
Xmin=i;
FailCount=0;
for(i=oldX; i<IMG_X+IMG_W; i++)
{
ReadColor(i, oldY, &rgb);
RGB2HSL(&rgb, &hls);
if(!ColorMatch(&hls, condition))
FailCount++;
if(FailCount>(((condition->WIDTH_MIN+condition->WIDTH_MAX)>>2)>>ALLOW_FAIL_PER))
break;
}
Xmax=i;
FailCount=0;
for(i=oldY; i>IMG_Y; i--)
{
ReadColor(oldX, i, &rgb);
RGB2HSL(&rgb, &hls);
if(!ColorMatch(&hls, condition))
FailCount++;
if(FailCount>(((condition->HEIGHT_MIN+condition->HEIGHT_MAX)>>2)>>ALLOW_FAIL_PER))
break;
}
Ymin=i;
FailCount=0;
for(i=oldY; i<IMG_Y+IMG_H; i++)
{
ReadColor(oldX, i, &rgb);
RGB2HSL(&rgb, &hls);
if(!ColorMatch(&hls, condition))
FailCount++;
if(FailCount>(((condition->HEIGHT_MIN+condition->HEIGHT_MAX)>>2)>>ALLOW_FAIL_PER))
break;
}
Ymax=i;
FailCount=0;
result->x = (Xmin + Xmax) / 2;
result->y = (Ymin + Ymax) / 2;
result->w = (Xmax - Xmin);
result->h = (Ymax - Ymin);
if( (result->w > condition->WIDTH_MIN) && (result->w < condition->WIDTH_MAX) &&
(result->h > condition->HEIGHT_MIN) && (result->h < condition->HEIGHT_MAX) )
return 1;
else
return 0;
}
int Trace(const TARGET_CONDITION* condition, RESULT* result_final)
{
unsigned int i;
static unsigned int x0, y0, Flag = 0;
static SEARCH_AREA area = {IMG_X, IMG_X+IMG_W, IMG_Y, IMG_Y+IMG_H};
RESULT result;
if(Flag == 0)
{
if(SearchCenter(&x0, &y0, condition, &area))
{
Flag = 1;
}
else
{
area.X_Start = IMG_X;
area.X_End = IMG_X+IMG_W;
area.Y_Start = IMG_Y;
area.Y_End = IMG_Y+IMG_H;
if(SearchCenter(&x0, &y0, condition, &area))
{
Flag = 0;
return 0;
}
}
}
result.x = x0;
result.y = y0;
for(i=0; i<ITERATER_NUM; i++)
{
Corrode(result.x, result.y, condition, &result); //′ó¸ˉê′ÖDDÄÏòía¸ˉê′£¬μÃμ½DÂμĸˉê′ÖDDÄ
}
if( Corrode(result.x, result.y, condition, &result) )
{
x0 = result.x;
y0 = result.y;
result_final->x = result.x;
result_final->y = result.y;
result_final->w = result.w;
result_final->h = result.h;
Flag = 1;
area.X_Start = result.x - ((result.w)>>1);
area.X_End = result.x + ((result.w)>>1);
area.Y_Start = result.y - ((result.h)>>1);
area.Y_End = result.y + ((result.h)>>1);
return 1;
}
else
{
Flag = 0;
return 0;
}
}
[/mw_shl_code]
一周热门 更多>