OV7670+卡屏+二值化+图像识别

2019-07-20 22:19发布

使用原子的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;

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
26条回答
shotgun
1楼-- · 2019-07-21 15:07
楼主你的程序调好没
dongberlin
2楼-- · 2019-07-21 18:50
pomo16 发表于 2017-8-4 11:10
你用stlink仿真一下,我试了一遍发现你的程序好像是数组越界了,我不大明白你的编程具体思路,所以具体问题 ...

是数组越界了,请问你有好的相关的算法可以开源看一下吗?换了好几种思路都不能实现
dongberlin
3楼-- · 2019-07-21 23:57
 精彩回答 2  元偷偷看……
dongberlin
4楼-- · 2019-07-21 23:58
 精彩回答 2  元偷偷看……
dongberlin
5楼-- · 2019-07-22 01:53
诸位大佬有相关的算法或者已经实现的摄像头的程序给我们开源一下下,拜谢
dongberlin
6楼-- · 2019-07-22 04:14
把这个贴出来,各位拿回去移植,有成功的记得回来贴出来[mw_shl_code=c,true]#include "stm32f10x.h"
#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  &#214;÷oˉêy
  * @param  &#206;T
  * @retval &#206;T
  */
int main(void)
{       
        //uint8_t status;
       
        LED_GPIO_Config();
        LED_BLUE;
        USART_Config();
        SPI_FLASH_Init();
        ILI9341_Init();        //LCD 3&#245;ê&#188;&#187;ˉ
        ILI9341_GramScan( 2 );        //óò&#207;&#194;&#189;&#199;->×óé&#207;&#189;&#199;
        ILI9341_Clear(0,0,320,240,macBLACK);//&#199;&#229;&#198;á£&#172;&#207;&#212;ê&#190;è&#171;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};

//ê&#182;±eμ&#196;ê&#199;&#194;ìé&#171;
TARGET_CONDITION condition={
        60,                                 //&#196;&#191;±ê×&#238;D&#161;é&#171;&#182;è£&#172;H_MIN
        110,       //&#196;&#191;±ê×&#238;′óé&#171;&#182;è£&#172;H_MAX
                   
        50,        //&#196;&#191;±ê×&#238;D&#161;±¥oí&#182;è£&#172;S_MIN
        240,       //&#196;&#191;±ê×&#238;′ó±¥oí&#182;è£&#172;S_MAX
                   
        60,        //&#196;&#191;±ê×&#238;D&#161;áá&#182;è£&#172;L_MIN
        190,       //&#196;&#191;±ê×&#238;′óáá&#182;è£&#172;L_MAX
                   
        40,        //&#196;&#191;±ê×&#238;D&#161;&#191;í&#182;è£&#172;WIDTH_MIN
        40,        //&#196;&#191;±ê×&#238;D&#161;&#184;&#223;&#182;è£&#172;HEIGHT_MIN
                   
        320,       //&#196;&#191;±ê×&#238;′ó&#191;í&#182;è£&#172;WIDTH_MAX
        240        //&#196;&#191;±ê×&#238;′ó&#184;&#223;&#182;è£&#172;HEIGHT_MAX
};

//2aê&#212;&#206;T&#206;ó
#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&#209;&#213;é&#171;
{
        unsigned char Hue;                                        //é&#171;&#182;è        ,[0,240]                               
        unsigned char Lightness;                //áá&#182;è,[0,240]             
        unsigned char Saturation;                //±¥oí&#182;è,[0,240]             
}COLOR_HLS;

typedef struct                                                //&#203;&#209;&#209;°&#199;&#248;óò
{
        unsigned int X_Start;
        unsigned int X_End;
        unsigned int Y_Start;
        unsigned int Y_End;
}SEARCH_AREA;


/**
* @brief  &#187;&#241;è&#161; ILI9341 &#207;&#212;ê&#190;&#198;÷é&#207;&#196;3ò&#187;&#184;&#246;×&#248;±êμ&#227;μ&#196;&#207;&#241;&#203;&#216;êy&#190;Y
* @param  usX £o&#212;úì&#216;&#182;¨é¨&#195;è·&#189;&#207;ò&#207;&#194;&#184;&#195;μ&#227;μ&#196;X×&#248;±ê
* @param  usY £o&#212;úì&#216;&#182;¨é¨&#195;è·&#189;&#207;ò&#207;&#194;&#184;&#195;μ&#227;μ&#196;Y×&#248;±ê
* @retval &#207;&#241;&#203;&#216;êy&#190;Y
*/
//uint16_t ILI9341_GetPointPixel( uint16_t usX, uint16_t usY )
#define getRGBColor_16bits ILI9341_GetPointPixel

/**
* @brief  &#182;áè&#161;&#196;3ò&#187;μ&#227;&#209;&#213;é&#171;êy&#190;Y
* @param  usX £o&#184;&#195;μ&#227;μ&#196;X×&#248;±ê
* @param  usY £o&#184;&#195;μ&#227;μ&#196;Y×&#248;±ê
* @param  color_rgb £oCOLOR_RGB&#189;á11ì&#229;£&#172;′&#230;′¢&#209;&#213;é&#171;êy&#190;Y
* @retval &#206;T
*/
static void ReadColor( uint16_t usX, uint16_t usY, COLOR_RGB* color_rgb )
{
        unsigned short rgb;
       
        rgb = getRGBColor_16bits( usX, usY );                                        //&#187;&#241;è&#161;&#209;&#213;é&#171;êy&#190;Y
       
        //×a&#187;&#187;3é&#214;μóò&#206;a[0,255]μ&#196;èy&#212;-é&#171;&#214;μ
        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&#189;á11ì&#229;£&#172;′&#230;′¢RGB&#184;&#241;ê&#189;&#209;&#213;é&#171;êy&#190;Y
* @param  color_hls £oCOLOR_HLS&#189;á11ì&#229;£&#172;′&#230;′¢HLS&#184;&#241;ê&#189;&#209;&#213;é&#171;êy&#190;Y
* @retval &#206;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;
       
        //&#188;&#198;&#203;&#227;l£&#172;áá&#182;è
        l = ( max + min ) * 240 / 255 / 2;
       
        //&#188;&#198;&#203;&#227;h£&#172;é&#171;&#182;è
        if( max == min )//&#206;T&#182;¨ò&#229;
        {
                s = 0;
                h = 0;
        }
        else
        {
                //&#188;&#198;&#203;&#227;é&#171;&#182;è
                if( max == r )
                {
                        if( min == b )//h&#189;éóú0μ&#189;40
                        {
                                h = 40 * ( g - b ) / dif;
                        }
                        else if( min == g )//h&#189;éóú200μ&#189;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;
                }
               
                //&#188;&#198;&#203;&#227;±¥oí&#182;è
                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;                                                        //é&#171;&#182;è
        color_hls->Lightness = l;                                //áá&#182;è
        color_hls->Saturation = s;                        //±¥oí&#182;è
       
}

/**
* @brief  &#209;&#213;é&#171;&#198;¥&#197;&#228;
* @param  color_hls £oCOLOR_HLS&#189;á11ì&#229;£&#172;′&#230;′¢HLS&#184;&#241;ê&#189;&#209;&#213;é&#171;êy&#190;Y
* @param  condition £oTARGET_CONDITION&#189;á11ì&#229;£&#172;′&#230;·&#197;&#207;£í&#251;μ&#196;&#209;&#213;é&#171;êy&#190;Y&#227;D&#214;μ
* @retval 1£o&#207;&#241;&#203;&#216;μ&#227;&#209;&#213;é&#171;&#212;ú&#196;&#191;±ê·&#182;&#206;§&#196;ú£&#187;0£o&#207;&#241;&#203;&#216;μ&#227;&#209;&#213;é&#171;2&#187;&#212;ú&#196;&#191;±ê·&#182;&#206;§&#196;ú&#161;£
*/
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  &#209;°&#213;ò&#184;ˉê′&#214;DD&#196;
* @param  x £o&#184;ˉê′&#214;DD&#196;x×&#248;±ê
* @param  y £o&#184;ˉê′&#214;DD&#196;y×&#248;±ê
* @param  condition £oTARGET_CONDITION&#189;á11ì&#229;£&#172;′&#230;·&#197;&#207;£í&#251;μ&#196;&#209;&#213;é&#171;êy&#190;Y&#227;D&#214;μ
* @param  area £oSEARCH_AREA&#189;á11ì&#229;£&#172;2é&#213;ò&#184;ˉê′&#214;DD&#196;μ&#196;&#199;&#248;óò
* @retval 1£o&#213;òμ&#189;á&#203;&#184;ˉê′&#214;DD&#196;£&#172;x&#161;¢y&#206;a&#184;ˉê′&#214;DD&#196;μ&#196;×&#248;±ê£&#187;0£o&#195;&#187;óD&#213;òμ&#189;&#184;ˉê′&#214;DD&#196;&#161;£
*/
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  ′ó&#184;ˉê′&#214;DD&#196;&#207;òía&#184;ˉê′£&#172;μ&#195;μ&#189;D&#194;μ&#196;&#184;ˉê′&#214;DD&#196;
* @param  oldX £o&#207;è&#199;°μ&#196;&#184;ˉê′&#214;DD&#196;x×&#248;±ê
* @param  oldX £o&#207;è&#199;°μ&#196;&#184;ˉê′&#214;DD&#196;y×&#248;±ê
* @param  condition £oTARGET_CONDITION&#189;á11ì&#229;£&#172;′&#230;·&#197;&#207;£í&#251;μ&#196;&#209;&#213;é&#171;êy&#190;Y&#227;D&#214;μ
* @param  result £oRESULT&#189;á11ì&#229;£&#172;′&#230;·&#197;&#188;ì2a&#189;á1&#251;
* @retval 1£o&#188;ì2a3é1|£&#187;0£o&#188;ì2a꧰ü&#161;£
*/
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);        //′ó&#184;ˉê′&#214;DD&#196;&#207;òía&#184;ˉê′£&#172;μ&#195;μ&#189;D&#194;μ&#196;&#184;ˉê′&#214;DD&#196;
               
        }
       
        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]

一周热门 更多>