Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
17 years ago

DE2_TV searching XY coordinates of pixels

Hi @all,

I am currently working with the DE2 Dev.&Edu. Board with Cyclone II.

In my project I am supposed to do a simple blob detection. The blobs are represented by white dots on black background.

Since I am new I decided to start with the DE2_TV example to become familiar with the dataflow. If I did understand it correct the program does the manipulation of the data pixel-wise, which means that the information which pixel it is actually manipulating should be available.

But I am a little bit confused which register does hold the information.

I thought it should be the ports oCurrent_X and oCurrent_Y from the VGA_Ctrl module, but if thats the case why is the register 11 bit.

This would allow a resolution of 2048x2048 (I know this is not the correct relation, it's just a example).

But the output of the VGA has only a resolution of 640 x 480, so the coordinates of X and Y should be lay inbetween.

Can someone help me here?

Where can I get the X and Y coordinates for the pixels?

regards,

Alex

12 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Do the coordinates change on every clock tick?

    How can I make sure that I don't proceed a pixel twice or miss a pixel?

    module run_line_detection(CLK_27, CLK_50, iReset, iVGA_R, iVGA_B, iVGA_G, iPosX, iPosY, iThresh, 
            iVGA_BLANK, iDIG, oVGA_R, oVGA_B, oVGA_G, oTXD_DATA, oTXD_Start, ProceedingA_Run, previousPosX);
    // INPUT
    input            iThresh;
    input            iVGA_R;
    input            iVGA_B;
    input            iVGA_G;
    input            iPosX;
    input            iPosY;
    input         CLK_27, iReset, CLK_50;
    input          iDIG;
    input                iVGA_BLANK;
    // OUTPUT
    output reg        oVGA_R;
    output reg        oVGA_B;
    output reg        oVGA_G;
    output reg      oTXD_DATA;
    output reg            oTXD_Start;
    // INTERNAL
    parameter TRUE = 1'b1;
    parameter FALSE = 1'b0;
    output reg ProceedingA_Run;  //flag to determine if pixel belongs to a run
    output reg  previousPosX;  
    reg  previousPosY;  
    reg  pixelPosX;  //store start position of run on X-Axis
    reg  pixelPosY;  //store start position of run on Y-Axis
    reg   pixelRunLength; //count number of pixels belonging to run
    reg  runRegister;//storage for detected runs
    reg        foundRun;  //global counter for detected runs
    reg  writeBank; //flag to switch between write commands
    reg  frameCounter; //counter for frames 1-3 to change pointer on run-register in SRAM
    reg  counter;
    always@(posedge CLK_27)
    begin
        if(!iReset)
        begin
            previousPosX = -1'd1;
            previousPosY = -1'd1;
            ProceedingA_Run = FALSE;
            counter = 0;
        end
            
        if ( (iPosX <= 640) && (iPosY <= 480) )
        begin
                //value > Threshold => pixel belongs to blob
                if((iVGA_R > iThresh) && (iVGA_G > iThresh) && (iVGA_B > iThresh) )
                begin
                    oVGA_R = iVGA_R;
                    oVGA_G = iVGA_G;
                    oVGA_B = iVGA_B;
                    
                    if(iVGA_BLANK)
                    begin
                        if(iPosX == (previousPosX +1))
                        begin
                    
                            //Pixel is start point of a new run
                            if( ProceedingA_Run == FALSE )
                            begin
                                ProceedingA_Run = TRUE;
                                pixelPosX = iPosX;
                                pixelPosY = iPosY;
                                pixelRunLength = 0;
                            end
                            //increase number of counted pixels for current run
                            pixelRunLength = pixelRunLength + 1; 
                        end
                        else
                        begin
                            //Actually proceeding a run, but current pixel does not belong to it the end of the run is reached
                            if( ProceedingA_Run == TRUE )
                            begin
                                ProceedingA_Run = FALSE;
                                //store run only if longer than 1 pixel
                                if( pixelRunLength > 1 )
                                begin
                                    runRegister <= {pixelPosX, pixelPosY, pixelRunLength};
                                    foundRun = TRUE;
                                end
                                else
                                begin
                                    foundRun = FALSE;
                                end
                            end        
                        end
                    end //end VGA_BLANK                
                end
                else
                begin    
                    if(iVGA_BLANK)
                    begin                        
                    //Actually proceeding a run, but current pixel does not belong to it the end of the run is reached
                        if( ProceedingA_Run == TRUE )
                        begin
                            ProceedingA_Run = FALSE;
                            //store run only if longer than 1 pixel
                            if( pixelRunLength > 1 )
                            begin
                                runRegister <= {pixelPosX, pixelPosY, pixelRunLength};
                                foundRun = TRUE;
                            end
                            else
                            begin
                                foundRun = FALSE;
                            end
                        end
                    end //end VGA_BLANK        
                    oVGA_R = 10'b0000000000;oVGA_G = 10'b0000000000;oVGA_B = 10'b0000000000;        
                end // threshold
        end //if ( iPosX <= 640 && iPosY <= 480 )
        else
        begin
            foundRun = FALSE;
        end
        
        if(foundRun == TRUE)
        begin
            foundRun = FALSE;
            runRegister <= {8'd200, 8'd170, 8'd15};
        end
            
        previousPosX = iPosX;
        previousPosY = iPosY;
        
                
        //change register for runs if end of frame reached
        if( (iPosX == 640) && (iPosY == 480 ))
        begin
            previousPosX = -1;
            previousPosY = -1;
            ProceedingA_Run = FALSE;
            
        end    
        
        
        if(foundRun) begin
            tmpRun = runRegister;
            TXD_Buffer = {TXD_Buffer, tmpRun, 2'h0A};
            TXD_Buffer_Flag = {TXD_Buffer_Flag, 5'b11111};
        end
        
        if(TXD_Buffer_Flag) begin
            oTXD_Start = 1'b1;
            oTXD_DATA = TXD_Buffer;
        end
        else
        begin
            oTXD_Start = 1'b0;
        end
        
        TXD_Buffer_Flag = {TXD_Buffer_Flag, 1'b0};
        TXD_Buffer = {TXD_Buffer,8'b00000000};
    end
    endmodule
    

    I have tested this code now with an wave input file. But every time when the procedure detects a pixel as above the threshold, the control variable proceedinga_run becomes undefined or represents 0 and 1 at the same time.

    Isn't possible to use register values in following iterations?

    Do they get lost?

    If I check for the previous position previousposx it works very well.

    Should I start from scratch or even change to SystemC ?

    I've invested now more than 2 months of work and don't make real efforts. Maybe doing it in Verilog was a bad decision?!

    thanks for your support
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Yes, you are right. (oCurrent_X, oCurrent_Y) means coordinates for the pixels while (oVGA_BLANK==1). Never mind bit length.