⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 framemgr.c

📁 he AVRcam source files were built using the WinAVR distribution (version 3.3.1 of GCC). I haven t t
💻 C
📖 第 1 页 / 共 2 页
字号:
			lineCount = 0;
			currentState = ST_FrameMgr_idle;
			
			/* disable the PCLK counting overflow interrupt */
			TIMSK &= DISABLE_PCLK_TIMER1_OVERFLOW_BITMASK;
			
			CamConfig_setCamReg(0x11,0x00);  /* reset the frame rate to normal*/
			CamConfig_sendFifoCmds();
		}
		else
		{
			/* we have more lines to acquire in this frame, so keep on truckin...*/
			PUBLISH_FAST_EVENT(FEV_PROCESS_LINE_COMPLETE);
		}
	}
	else if (currentState == ST_FrameMgr_TrackingFrame)
	{
#ifdef DEBUG_TRACKED_LINE	
		/* send the received line over serial...this should only send
		until a pixelCount == 176 */
		pSendData = currentLineBuffer;
		itoa(trackedLineCount,asciiBuffer,10);
		UIMgr_txBuffer(asciiBuffer,3);
		UIMgr_txBuffer(" ",1);
		while(pixelCount < ACTUAL_NUM_PIXELS_IN_A_LINE)  
		{
			memset(asciiBuffer,0x00,5);
			itoa(*pSendData++,asciiBuffer,10);	/* color is first byte */
			UIMgr_txBuffer(asciiBuffer,3); /* 3 ascii bytes for data */
			UIMgr_txBuffer(" ",1);

			pixelCount += *pSendData;	/* run-length is second byte */
			memset(asciiBuffer,0x00,5);
			itoa(*pSendData++,asciiBuffer,10);
			UIMgr_txBuffer(asciiBuffer,3);
			UIMgr_txBuffer(" ",1);
		}
		UIMgr_txBuffer("\n\r",2);

		trackedLineCount++;
		if (trackedLineCount == 144)
		{
			UIMgr_txBuffer("  FC  \n\r",8);
			trackedLineCount = 0;
			PUBLISH_EVENT(EV_PROCESS_FRAME_COMPLETE);
		}
		else
		{
			PUBLISH_EVENT(EV_PROCESS_LINE_COMPLETE);
		}	
#else
        /* determine if any of the RLE blocks overlap */
		FrameMgr_findConnectedness();
        
        /* we also want to remove any objects that are less than
        a minimum height...we already removed portions of the 
        run-length that are less than MIN_PIXEL_WIDTH in the
        findConnectedness() routine...doing it here instead of 
        a function to speed things up...this may end up slowing down the
        frame rate slightly, and can be removed if this isn't needed */
  
        /* run this routine once every 8 lines */       
        if ( (trackedLineCount & RUN_OBJECT_FILTER_MASK) == RUN_OBJECT_FILTER_MASK)
        {
            for (i=0; i<MAX_TRACKED_OBJECTS; i++)
            {
                if ( *(pTrackedObjectData + VALID_OBJECT_OFFSET) == TRUE)
                {
                    /* check to see if the object is already in
                    our past...i.e., its last */
                    if ( (*(pTrackedObjectData + Y_LOWER_RIGHT_OFFSET) - 
                          *(pTrackedObjectData + Y_UPPER_LEFT_OFFSET)) < MIN_OBJECT_TRACKING_HEIGHT)
                    {
                        /* the object is less than the minimum height...see if it is adjacent
                        to the current line we just processed...if so, leave it here...otherwise,
                        it needs to be invalidated since its too small */
                        if ( trackedLineCount - *(pTrackedObjectData + Y_LOWER_RIGHT_OFFSET) > 2)
                        {
                            /* invalidate the object */
                            *(pTrackedObjectData + VALID_OBJECT_OFFSET) = FALSE;
                            numCurrTrackedObjects--;
                        }
                    }
                }
                pTrackedObjectData += SIZE_OF_TRACKED_OBJECT;
            }
        }     
 
		trackedLineCount++;
		if (trackedLineCount == ACTUAL_NUM_LINES_IN_A_FRAME)
		{
			/* an entire frame of tracking data has been acquired, so
			publish an event letting the system know this fact */
			PUBLISH_EVENT(EV_ACQUIRE_FRAME_COMPLETE);
			/* disable the PCLK counting overflow interrupt */
			TIMSK &= DISABLE_PCLK_TIMER1_OVERFLOW_BITMASK;
			trackedLineCount = 0;
		}
		else
		{
			PUBLISH_FAST_EVENT(FEV_PROCESS_LINE_COMPLETE);
		}
#endif		
	}
	else
	{
		/* ...and here? */
	}
}

/***********************************************************
	Function Name: FrameMgr_processFrame
	Function Description: This function is responsible for
	parsing the completed frame and performing all actions
	needed at this level.
	Inputs:  none
	Outputs: none
***********************************************************/	
void FrameMgr_processFrame(void)
{
	unsigned char i,k,color;
#if DEBUG_FRAME_DATA    
	unsigned char asciiBuffer[5];
    unsigned char j;
#endif    
	unsigned char *pTableData = (unsigned char *)pCurrentTrackedObjectTable;
	unsigned char tmpUpperLeftX,tmpUpperLeftY,tmpLowerRightX,tmpLowerRightY;
	
#if DEBUG_FRAME_DATA	
	/* we want to send all of the currently tracked table out
	the serial port for debugging */
	for (i=0; i<numCurrTrackedObjects; i++)
	{
		UIMgr_txBuffer("----------\r\n",12);
		for (j=0; j<SIZE_OF_TRACKED_OBJECT; j++)
		{
			memset(asciiBuffer,0x00,5);
			itoa(*pTableData++,asciiBuffer,10);
			UIMgr_txBuffer(asciiBuffer,3); /* 3 ascii bytes for data
														+ 1 space */
			UIMgr_txBuffer("\r\n",2);
		}
	}
	
	/* finally, send a new line */
	UIMgr_txBuffer("\r\n",2);
	
	memset(asciiBuffer,0x00,5);
	itoa(numCurrTrackedObjects,asciiBuffer,10);
	UIMgr_txBuffer(asciiBuffer,3);
	UIMgr_txBuffer(" PFC\r\n",5);

#else	
	/* we only send tracking packets if there are tracked objects */	        
    
	if (numCurrTrackedObjects > 0)
	{		
		UIMgr_writeTxFifo(0x0A);					/* header byte for a tracking packet */
        /* reset the pointer */
        pTableData = (unsigned char *)pCurrentTrackedObjectTable;
        
		UIMgr_writeTxFifo(numCurrTrackedObjects);	/* num of objects tracked */
		for (i=0; i<MAX_TRACKED_OBJECTS; i++)
		{
            /* we only want to process objects that have their objectValid flag
            set to TRUE */
            if ( *(pTableData + VALID_OBJECT_OFFSET) == TRUE)
            {
                /* the object is valid...convert the color from bit position to value...remember, 
                each bit in the "color" byte corresponds to a color */
                k=0;
                color = *(pTableData + COLOR_OFFSET);
                if (color == 128) k=0;
                else if (color == 64) k=1;
                else if (color == 32) k=2;
                else if (color == 16) k=3;
                else if (color == 8)  k=4;
                else if (color == 4)  k=5;
                else if (color == 2)  k=6;
                else if (color == 1)  k=7;
                
                tmpUpperLeftX = *(pTableData + X_UPPER_LEFT_OFFSET);	    /* get the upper left X */
                tmpUpperLeftY = *(pTableData + Y_UPPER_LEFT_OFFSET);		/* get the upper left Y */		
                tmpLowerRightX = *(pTableData + X_LOWER_RIGHT_OFFSET);		/* get the lower right X */
                tmpLowerRightY = *(pTableData + Y_LOWER_RIGHT_OFFSET);		/* get the lower right Y */	                
                
                UIMgr_writeTxFifo(k);				  	/* send the color first */
                UIMgr_writeTxFifo(tmpUpperLeftX);
                UIMgr_writeTxFifo(tmpUpperLeftY);
                UIMgr_writeTxFifo(tmpLowerRightX);
                UIMgr_writeTxFifo(tmpLowerRightY);			
            }

            /* move our pointer up to the beginning of the next object */
            pTableData += SIZE_OF_TRACKED_OBJECT;
        }
		
		/* all done...send the end of tracking packets char */
		UIMgr_writeTxFifo(0xFF);
	}	
#endif	

    /* the tracked object table will be cleared out right before we start
    to wait for VSYNC to indicate a new frame...so it doesn't need to be
    done now */
    
	/* schedule the next action to acquire a new frame */	
	PUBLISH_EVENT(EV_PROCESS_FRAME_COMPLETE);
}

/***********************************************************
	Function Name: FrameMgr_findConnectedness
	Function Description: This function is responsible for
	finding the connectedness between two particular run-
	length encoded lines of pixel data.  It updates the
	trackingTable as needed.
	Inputs:  none
	Outputs: none
***********************************************************/	
static void FrameMgr_findConnectedness(void)
{
	trackedColor_t currColor;
	unsigned char *pCurrLineColorInfo = currentLineBuffer;
	unsigned char *pTrackedObjectData;
	register unsigned char currPixelRunStart=0;
	register unsigned char currPixelRunFinish=0; 
	register unsigned char lastLineXStart=0;
	register unsigned char lastLineXFinish=0;  
	register unsigned char runLength=1;
	unsigned char i;
	bool_t colorConnected;	
	
	do
	{
		/* grab both the current color and the number of pixels
		in the run...remember, pixels start at 1, not 0! */
		colorConnected = FALSE;
		currColor = *pCurrLineColorInfo++;
		currPixelRunStart += runLength;
		runLength = *pCurrLineColorInfo++;
		currPixelRunFinish += runLength;
      
        /* make sure that the run-length is at least as wide as
        the minimum horizontal tracking width, and we care about the color */ 
        
		if ( (currColor != notTracked) && (runLength > MIN_OBJECT_TRACKING_WIDTH) )
		{			
            /* this run contains a color we care about, so 
			either it will begin a new tracked object, or it
			is connected to a currently tracked object...
			compare it with each object in the tracking
			table...we can't just look at the numTrackedObjects because
            it is entirely possible that the first couple of objects could
            be invalid...

            NOTE: Instead of accessing each element in the trackedObjectTable
            through the 'i' index, and then accessing the fields in each structure,
            a pointer to each entry is established each time through the loop, followed
            by accessing the elements through specified offsets.  GCC seems to be
            able to optimize this code much better than simply accessing the elements
            of each structure in the array the more normal way...*/
            
            pTrackedObjectData = (unsigned char *)pCurrentTrackedObjectTable;
			for (i=0; i<MAX_TRACKED_OBJECTS; i++)
			{
				if ( (currColor == *(pTrackedObjectData + COLOR_OFFSET)) && 
                     (*(pTrackedObjectData + VALID_OBJECT_OFFSET) == TRUE) &&
                     (*(pTrackedObjectData + Y_LOWER_RIGHT_OFFSET) == trackedLineCount - 1) )
				{
					/* found a color match and the object is valid...check to see if there is
					connectedness */
					lastLineXStart = *(pTrackedObjectData + LAST_LINE_X_START_OFFSET);
					lastLineXFinish = *(pTrackedObjectData + LAST_LINE_X_FINISH_OFFSET);
					
					/* Check for the 5 following types of line connectedness:
					---------------------
					|                   |
					---------------------
					         -------------------------
							 |                       |
							 -------------------------  */
					if ( (	(currPixelRunStart >= lastLineXStart) &&
							(currPixelRunStart <= lastLineXFinish) )  ||
							
					/*               ---------------------
					                 |                   |
									 ---------------------
						-------------------
						|                 |
						-------------------  
						                   OR
						     ------------------------------
							 |                            |
							 ------------------------------
							              ---------
										  |       |
										  ---------  */
						 (	(currPixelRunFinish >= lastLineXStart) && 
							(currPixelRunFinish <= lastLineXFinish) ) ||
							
							
					/*     -------------------------------
					       |                             |
						   -------------------------------
						   -------------------------------
						   |                             |
						   -------------------------------
						                  OR
								     -------------
									 |           |
									 -------------
							-------------------------------
							|                             |
							-------------------------------   */
						 (  (currPixelRunStart <= lastLineXStart) &&
							(currPixelRunFinish >= lastLineXFinish) ) )
					{
						/* THERE IS CONNECTEDNESS...update the lastLineXStart and lastLineXFinish
						data pointed to by pTrackedObjectData */
						*(pTrackedObjectData + LAST_LINE_X_START_OFFSET) = currPixelRunStart;
						*(pTrackedObjectData + LAST_LINE_X_FINISH_OFFSET) = currPixelRunFinish;
						
						/* check if the bounding box needs to be updated */
						if (*(pTrackedObjectData + X_UPPER_LEFT_OFFSET) > currPixelRunStart)
						{
							/* need to update the bounding box for the upper left point to 
							enclose this new left-most point...we never have to update the
							upper left Y point, since each scan line we process moves from
							top to bottom */
							*(pTrackedObjectData + X_UPPER_LEFT_OFFSET) = currPixelRunStart;
						}

						if ( *(pTrackedObjectData + X_LOWER_RIGHT_OFFSET) < currPixelRunFinish)
						{
							/* need to update the bounding box for the lower right X point to
							enclose this new right-most point */
							*(pTrackedObjectData + X_LOWER_RIGHT_OFFSET) = currPixelRunFinish;
						}
						
						/* the lower right 'y' point always gets updated when connectedness is found */
						*(pTrackedObjectData + Y_LOWER_RIGHT_OFFSET) = trackedLineCount;
						
						/* set a flag indicating that that color run is part of another
						object and thus doesn't need to be added as a new entry into the
						tracking table */
						colorConnected = TRUE;
						break;
					}
				}
                
                /* go to the next object */
                pTrackedObjectData += SIZE_OF_TRACKED_OBJECT;
			}
			
			if (colorConnected == FALSE)
			{
				/* a new entry needs to be made to the tracking table, since we have
				a run-length with a color, and it isn't connected to anything...but we
				can only do this if there is space left in the trackedObject table */
				if (numCurrTrackedObjects < MAX_TRACKED_OBJECTS)
				{                
                    /* space is available...add the object...but first we need to find an
                    invalid object in the object tracking table */
                    pTrackedObjectData = (unsigned char *)pCurrentTrackedObjectTable;
                    for (i=0; i<MAX_TRACKED_OBJECTS; i++)
                    {
                        if ( *(pTrackedObjectData + VALID_OBJECT_OFFSET) == FALSE)  break;
                        
                        /* if we haven't broken above, then the object must have been valid...
                        go ahead and move the pointer to the next object to check it */
                        pTrackedObjectData += SIZE_OF_TRACKED_OBJECT;
                    }
                    
					
					/* now that we have a pointer to the tracked object to be updated, update all
					the fields */
					*(pTrackedObjectData + COLOR_OFFSET)                = currColor;			/* color */
					*(pTrackedObjectData + LAST_LINE_X_START_OFFSET)    = currPixelRunStart; 	/* lastLineXStart */
					*(pTrackedObjectData + LAST_LINE_X_FINISH_OFFSET)   = currPixelRunFinish;	/* lastLineXFinish */
					*(pTrackedObjectData + X_UPPER_LEFT_OFFSET)         = currPixelRunStart;	/* x_upperLeft */
					*(pTrackedObjectData + Y_UPPER_LEFT_OFFSET)         = trackedLineCount;	/* y_upperLeft */
					*(pTrackedObjectData + X_LOWER_RIGHT_OFFSET)        = currPixelRunFinish;	/* x_lowerRight */
					*(pTrackedObjectData + Y_LOWER_RIGHT_OFFSET)        = trackedLineCount;	/* y_lowerRight */
                    *(pTrackedObjectData + VALID_OBJECT_OFFSET)         = TRUE;                /* objectValid flag */
						
					numCurrTrackedObjects++;
				}
			}
            
            /* move the pointer to the beginning of the next tracked object */
            pTrackedObjectData += SIZE_OF_TRACKED_OBJECT;
		}
	} while(currPixelRunFinish < ACTUAL_NUM_PIXELS_IN_A_LINE);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -