コード例 #1
0
////////////////////////////////////////////////////////////////////////////////
//
// Function Name: IVA_DisposeData
//
// Description  : Releases the memory allocated in the IVA_Data structure
//
// Parameters   : ivaData  -  Internal data structure
//
// Return Value : success
//
////////////////////////////////////////////////////////////////////////////////
static int IVA_DisposeData(IVA_Data* ivaData)
{
    int i;


    // Releases the memory allocated for the image buffers.
    for (i = 0 ; i < IVA_MAX_BUFFERS ; i++)
        imaqDispose(ivaData->buffers[i]);

    // Releases the memory allocated for the array of measurements.
    for (i = 0 ; i < ivaData->numSteps ; i++)
        IVA_DisposeStepResults(ivaData, i);

    free(ivaData->stepResults);

    // Dispose of coordinate systems
    if (ivaData->numCoordSys)
    {
        free(ivaData->baseCoordinateSystems);
        free(ivaData->MeasurementSystems);
    }

    free(ivaData);

    return true;
}
コード例 #2
0
void CameraServer::FreeImageData(std::tuple<uint8_t*, unsigned int, unsigned int, bool> imageData) {
  if (std::get<3>(imageData)) imaqDispose(std::get<0>(imageData));
  else if (std::get<0>(imageData) != nullptr) {
    std::unique_lock<std::recursive_mutex> lock(m_imageMutex);
    m_dataPool.push_back(std::get<0>(imageData));
  }
}
コード例 #3
0
////////////////////////////////////////////////////////////////////////////////
//
// Function Name: IVA_CLRThreshold
//
// Description  : Thresholds a color image.
//
// Parameters   : image      -  Input image
//                min1       -  Minimum range for the first plane
//                max1       -  Maximum range for the first plane
//                min2       -  Minimum range for the second plane
//                max2       -  Maximum range for the second plane
//                min3       -  Minimum range for the third plane
//                max3       -  Maximum range for the third plane
//                colorMode  -  Color space in which to perform the threshold
//
// Return Value : success
//
////////////////////////////////////////////////////////////////////////////////
static int IVA_CLRThreshold(Image* image, int min1, int max1, int min2, int max2, int min3, int max3, int colorMode)
{
    int success = 1;
    Image* thresholdImage;
    Range plane1Range;
    Range plane2Range;
    Range plane3Range;


    //-------------------------------------------------------------------//
    //                          Color Threshold                          //
    //-------------------------------------------------------------------//

    // Creates an 8 bit image for the thresholded image.
    VisionErrChk(thresholdImage = imaqCreateImage(IMAQ_IMAGE_U8, 7));

    // Set the threshold range for the 3 planes.
    plane1Range.minValue = min1;
    plane1Range.maxValue = max1;
    plane2Range.minValue = min2;
    plane2Range.maxValue = max2;
    plane3Range.minValue = min3;
    plane3Range.maxValue = max3;

    // Thresholds the color image.
    VisionErrChk(imaqColorThreshold(thresholdImage, image, 1, colorMode, &plane1Range, &plane2Range, &plane3Range));

    // Copies the threshold image in the souce image.
    VisionErrChk(imaqDuplicate(image, thresholdImage));

Error:
    imaqDispose(thresholdImage);

    return success;
}
コード例 #4
0
double VisionSubsystem::scoreXEdge(BinaryImage *image, ParticleAnalysisReport *report) {
	double total = 0;
	LinearAverages *averages = imaqLinearAverages2(image->GetImaqImage(), IMAQ_COLUMN_AVERAGES, report->boundingRect);
	for(int i=0; i < (averages->columnCount); i++) {
		if(xMin[i*(XMINSIZE-1)/averages->columnCount] < averages->columnAverages[i] && averages->columnAverages[i] < xMax[i*(XMAXSIZE-1)/averages->columnCount]) {
			total++;
		}
	}
	total = 100*total/(averages->columnCount);
	imaqDispose(averages);
	return total;
}
コード例 #5
0
ファイル: CameraMod.c プロジェクト: zenki2001cn/SnippetCode
int sgl_release_camera_data(CameraSgl *camera)
{
	CameraData *data = &camera->data;

	if (data->image != NULL) {
		imaqDispose (data->image);
		data->image = NULL;
	}

	data->buffer_num = 0;

	return 0;
}
コード例 #6
0
double VisionSubsystem::scoreYEdge(BinaryImage *image, ParticleAnalysisReport *report) {
	double total = 0;
	LinearAverages *averages = imaqLinearAverages2(image->GetImaqImage(), IMAQ_ROW_AVERAGES, report->boundingRect);
	for(int i=0; i < (averages->rowCount); i++){
		if(yMin[i*(YMINSIZE-1)/averages->rowCount] < averages->rowAverages[i] 
		   && averages->rowAverages[i] < yMax[i*(YMAXSIZE-1)/averages->rowCount]){
			total++;
		}
	}
	total = 100*total/(averages->rowCount);		//convert to score 0-100
	imaqDispose(averages);						//let IMAQ dispose of the averages struct
	return total;
}
コード例 #7
0
ファイル: VisionAPI.cpp プロジェクト: 0xacf/wpilib
/**
* @brief Dispose of a list of objects. Supports any object created on the heap.
* 
* @param functionName The name of the function
* @param ... A list of pointers to structures that need to be disposed of. 
* The last pointer in the list should always be set to NULL.
* 
* @return On success: 1. On failure: 0. To get extended error information, call GetLastError().
*/
int frcDispose( const char* functionName, ... ) /* Variable argument list */
{
    va_list disposalPtrList;   /* Input argument list */
    void* disposalPtr;         /* For iteration */
    int success, returnValue = 1;
    
    va_start( disposalPtrList, functionName );  /* start of variable list */
    disposalPtr = va_arg( disposalPtrList, void* );
    while( disposalPtr != NULL )     {
    	success = imaqDispose(disposalPtr);
        if (!success) {returnValue = 0;}
        disposalPtr = va_arg( disposalPtrList, void* );
    }
    return returnValue;
}
コード例 #8
0
double VisionSubsystemV2::scoreYEdge(BinaryImage *image, ParticleAnalysisReport *report) {
	double total = 0;
	LinearAverages *averages = imaqLinearAverages2(image->GetImaqImage(), IMAQ_ROW_AVERAGES, report->boundingRect);
	
	for(int i=0; i < (averages->rowCount); i++){
		if(yMinV2[i*(YMINSIZE-1)/averages->rowCount] < averages->rowAverages[i] && averages->rowAverages[i] < yMaxV2[i*(YMAXSIZE-1)/averages->rowCount]){
				total++;
		}
	}
	total = 100*total/(averages->rowCount);		//convert to score 0-100
	imaqDispose(averages);						//let IMAQ dispose of the averages struct
	#ifndef VISION_DEBUG_PRINTF_ENABLE
	printf("[VisionSubsystemV2] (scoreYEdge) The score of the Y-edge is %f\n", total);
	#endif	
	return total;
}
コード例 #9
0
double VisionSubsystemV2::scoreXEdge(BinaryImage *image, ParticleAnalysisReport *report) {
	double total = 0;
	LinearAverages *averages = imaqLinearAverages2(image->GetImaqImage(), IMAQ_COLUMN_AVERAGES, report->boundingRect);
	
	for(int i = 0; i < (averages->columnCount); i++) {
		if (xMinV2[i*(XMINSIZE - 1) / averages->columnCount] < averages->columnAverages[i] && averages->columnAverages[i] < xMaxV2[i*(XMAXSIZE - 1) / averages->columnCount]) {
			total++;
		}
	}
	total = 100*total/(averages->columnCount);
	imaqDispose(averages);
	#ifndef VISION_DEBUG_PRINTF_ENABLE
	printf("[VisionSubsystemV2] (scoreXEdge) The score of the X-edge is %f\n", total);
	#endif
	return total;
}
コード例 #10
0
ファイル: MonoImage.cpp プロジェクト: 128keaton/wpilib
/**
 * Look for ellipses in an image.
 * Given some input parameters, look for any number of ellipses in an image.
 * @param ellipseDescriptor Ellipse descriptor
 * @param curveOptions Curve options
 * @param shapeDetectionOptions Shape detection options
 * @param roi Region of Interest
 * @returns a vector of EllipseMatch structures (0 length vector on no match)
 */
vector<EllipseMatch> * MonoImage::DetectEllipses(
		EllipseDescriptor *ellipseDescriptor, CurveOptions *curveOptions,
		ShapeDetectionOptions *shapeDetectionOptions, ROI *roi)
{
	int numberOfMatches;
	EllipseMatch *e = imaqDetectEllipses(m_imaqImage, ellipseDescriptor,
										curveOptions, shapeDetectionOptions, roi, &numberOfMatches);
	vector<EllipseMatch> *ellipses = new vector<EllipseMatch>;
	if (e == NULL)
	{
		return ellipses;
	}
	for (int i = 0; i < numberOfMatches; i++)
	{
		ellipses->push_back(e[i]);
	}
	imaqDispose(e);
	return ellipses;
}
コード例 #11
0
ファイル: TargetReport.cpp プロジェクト: team3499/2013
/**
 * Computes a score based on the match between a template profile and the particle profile in the X direction. This method uses the
 * the column averages and the profile defined at the top of the sample to look for the solid vertical edges with
 * a hollow center.
 * 
 * @param image The image to use, should be the image before the convex hull is performed
 * @param report The Particle Analysis Report for the particle
 * 
 * @return The X Edge Score (0-100)
 */
double TargetReport::scoreXEdge(BinaryImage *image, ParticleAnalysisReport *report){
    double total = 0;

    const double xMax[XMAXSIZE] = {1.0, 1.0, 1.0, 1.0, 0.5, 0.5, 0.5, 0.5,
                                   0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5,
                                   0.5, 0.5, 0.5, 0.5, 1.0, 1.0, 1.0, 1.0};
    const double xMin[XMINSIZE] = {0.4, 0.6, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1,
                                   0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1,
                                   0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.6, 0.0};

    LinearAverages *averages = imaqLinearAverages2(image->GetImaqImage(), IMAQ_COLUMN_AVERAGES, report->boundingRect);
    for(int i=0; i < (averages->columnCount); i++){
        if(xMin[i*(XMINSIZE-1)/averages->columnCount] < averages->columnAverages[i] 
           && averages->columnAverages[i] < xMax[i*(XMAXSIZE-1)/averages->columnCount]){
            total++;
        }
    }
    total = 100*total/(averages->columnCount);        //convert to score 0-100
    imaqDispose(averages);                            //let IMAQ dispose of the averages struct
    return total;
}
コード例 #12
0
ファイル: VisionAPI.cpp プロジェクト: 0xacf/wpilib
/**
* @brief Dispose of one object. Supports any object created on the heap.
* 
* @param object object to dispose of
* @return On success: 1. On failure: 0. To get extended error information, call GetLastError().
*/
int frcDispose(void* object)  { return imaqDispose(object);	}
コード例 #13
0
	/****** AUTO FUNCTIONS END *******/
	void Autonomous()
	{
		int counter=0;
		int autonomousEngagement = 0;
		DriverStationLCD *screen = DriverStationLCD::GetInstance();	
		compressor.Start(); //starts compressor class
		rightArmSolenoid.Set(DoubleSolenoid::kReverse); //brings the arms down
		leftArmSolenoid.Set(DoubleSolenoid::kReverse);
		/*** ENSURES THE CATAPULT IS LOADED AND LOADS IF UNLOADED ***/
		if (leftLimitSwitch.Get() == 1 && rightLimitSwitch.Get() == 1)
		{
			winchMotor.Set(0.1); // Gears need to be moving slowly to allow the dog gear to engage properly
			dogSolenoid.Set(DoubleSolenoid::kForward); // Pushes the pneumatic piston forward to engage the dog gear
			Wait(0.2); // Giving the pistons time to engage properly
			winchMotor.Set(0); // Now that the dog gear is engaged, the gears do not have to move
			ratchetSolenoid.Set(DoubleSolenoid::kForward); // Pushes the pneumatic piston forward to engage the ratchet
			Wait(0.2); // Giving the pistons time to engage properly
		}
		while (leftLimitSwitch.Get() == 1 && rightLimitSwitch.Get() == 1) // If Limit Switch Buttons are not pressed
			{
			winchMotor.Set(1); //Now starts the winch motor to load the catapult
			}
		// If the Catapult Left &  Limit Switches are (0,0), (0,1), (1,0)
		{
			winchMotor.Set(0); // Stops the Winch Motor since one or more buttons are pressed
			if ((dogSolenoid.Get() == DoubleSolenoid::kReverse) && (ratchetSolenoid.Get() == DoubleSolenoid::kForward)) // If the Dog Gear is disengaged but the ratchet is engaged
				{
					winchMotor.Set(0.05); // Gears need to be moving slowly to allow the dog gear to engage properly. Might want to test this since the catapult's already loaded.
					dogSolenoid.Set(DoubleSolenoid::kForward); // Engages the dog gear so both dog gear and ratchet are engaged before shooting for safety
					Wait(0.1); // Giving the pistons time to engage properly
					winchMotor.Set(0); // Now that the dog gear is engaged, the gears do not have to move
				}
			else if ((dogSolenoid.Get() == DoubleSolenoid::kForward) && (ratchetSolenoid.Get() == DoubleSolenoid::kReverse)) // If the dog gear is engaged but the ratchet is disengaged
				{
					ratchetSolenoid.Set(DoubleSolenoid::kForward); // Engages the ratchet so that both dog gear and ratchet are engaged before shooting for safety
					Wait(0.1); // Giving the pistons time to engage properly
				}
		}
		/*** DONE LOADING THE CATAPULT ***/
		float pLower = 5; // min height of rectangle for comparison
		float pUpper = 15;	// max height of rectangle for comparison
		int criteriaCount = 1; // number of elements to include/exclude at a time
		int rejectMatches = 1;	// when set to true, particles that do not meet the criteria are discarded
		int connectivity = 1;	// declares connectivity value as 1; so corners are not ignored
		int filterFunction;	// removes small blobs
		int borderSetting;	// variable to store border settings, limit for rectangle
		int borderSize = 1;  // border for the camera frame (if you don't put this, DriverStation gets mad at you)
		ParticleFilterCriteria2 particleCriteria;	
		ParticleFilterOptions2 particleFilterOptions;
		int numParticles;
		particleCriteria.parameter = IMAQ_MT_BOUNDING_RECT_HEIGHT; //The Morphological measurement we use
		particleCriteria.lower = pLower; // The lower bound of the criteria range
		particleCriteria.upper = pUpper; // The upper bound of the criteria range
		particleCriteria.calibrated = FALSE; // We aren't calibrating to real world measurements. We don't need this.
		particleCriteria.exclude = TRUE; // Remove all particles that aren't in specific pLower and pUpper range
		particleFilterOptions.rejectMatches = rejectMatches; // Set to 1 above, so images that do not meet the criteria are discarded
		particleFilterOptions.rejectBorder = 0; // Set to 0 over here so border images are not discarded
		particleFilterOptions.connectivity8 = connectivity; // Sets the image image to 8 bit
		while ((IsAutonomous()))
		{
			if (logitech.GetRawButton(4))
				{
					autonomousEngagement = 1;
				}
			if (autonomousEngagement == 0) // If real autonomous is not engaged start
			{
				if (logitech.GetRawButton(1))
					{
						driveForward();
					}
				if (logitech.GetRawButton(9))
				{
					dogSolenoid.Set(DoubleSolenoid::kForward);		// Brings the pneumatic piston backward to raise the retrieval arm
					winchMotor.Set(0.1);
					Wait(0.3);
					ratchetSolenoid.Set(DoubleSolenoid::kForward);	// Pushes the pneumatic piston forward to lower the retrieval arm
					while(leftLimitSwitch.Get()==1 && rightLimitSwitch.Get()==1)
						{
							winchMotor.Set(1);
						}
				}
				if (logitech.GetRawButton(2))
				{
					autonomousCatapultRelease();
				}
				if (logitech.GetRawButton(3))
				{
					stopDriving();
				}
				if (logitech.GetRawButton(5))
				{
					turnLeft();
				}
				if (logitech.GetRawButton(7))
				{
					turnLeftMore();
				}
				if (logitech.GetRawButton(6))
				{
					turnRight();
				}
				if (logitech.GetRawButton(8))
				{
					turnRightMore();
				}
			}// If real autonomous is not engaged end
			HSLImage* imgpointer; // declares an image container as an HSL (hue-saturation-luminence) image
			imgpointer = camera.GetImage();	//tells camera to capture image
			ringLight.Set(Relay::kForward); //turns ringlight on
			BinaryImage* binIMG = NULL;	// declares a container to hold a binary image
			binIMG = imgpointer -> ThresholdHSL(0, 255, 0, 255, 235, 255);	// thresholds HSL image and places in the binary image container
			delete imgpointer;	// deletes the HSL image to free up memory on the cRIO
			Image* modifiedImage = imaqCreateImage(IMAQ_IMAGE_U8, 0); //create a binary 8-bit format shell for the image
			filterFunction = imaqParticleFilter4(modifiedImage, binIMG -> GetImaqImage(), &particleCriteria, criteriaCount, &particleFilterOptions, NULL, &numParticles); //The Particle Filter Function we use. (The ones before it are outdated)
			borderSetting = imaqSetBorderSize(modifiedImage, borderSize); // Sets a border size so DriverStation is happy
			delete binIMG; //Deletes the Binary image
			int functionCountParticles; // stores number of particles
			int particleAmount; // stores the number of particles for the measure particle function
			functionCountParticles = imaqCountParticles(modifiedImage, TRUE, &particleAmount); // Counts the number of particles
			int functionOne; // The first measuring particle function (specifically for particle #1)
			int functionTwo; // The second measuring particle function (specifically for particle #2)
			double particleOneOrientation; // TRULY ARBITRARY name of the first particle it find
			double particleTwoOrientation; // TRULY ARBITRARY name of the second particle it finds
			functionOne = imaqMeasureParticle(modifiedImage, 0, FALSE, IMAQ_MT_ORIENTATION, &particleOneOrientation); // Measures orientation of particle 1
			functionTwo = imaqMeasureParticle(modifiedImage, 1, FALSE, IMAQ_MT_ORIENTATION, &particleTwoOrientation); // Measures orientation of particle 2
			screen->PrintfLine(DriverStationLCD::kUser_Line2,"P1: %f", particleOneOrientation); // Prints particle 1's orientation
			screen->PrintfLine(DriverStationLCD::kUser_Line3,"P2: %f", particleTwoOrientation); // Prints particle 2's orientation
			imaqDispose(modifiedImage); // Deletes the filtered image
			/**LEFT POSITION**/
			if ((leftPositionSwitch.Get() == 1) && (rightPositionSwitch.Get() == 0)) // Left switch set on,  switch set off
			{
				screen -> PrintfLine(DriverStationLCD::kUser_Line1,"Left Position:F"); // Left position and facing forward			
				if ((particleOneOrientation > 0 && particleOneOrientation < 10) || (particleTwoOrientation > 0 && particleTwoOrientation < 10))
					
					// The target should be hot. Now it goes to the other goal.
					/* Theoretically particle 1 or 2 should register as exactly 0 (the particle is horizontal). We can edit these later. */
				{
					screen -> PrintfLine(DriverStationLCD::kUser_Line4,"Left Position Hot!");
					// These DEFINITELY need to be tested. All of them. Forreal.
					turnRight();
					//driveForward();
					Wait(3); 
					stopDriving();
					//autonomousCatapultRelease();
				}
				else // The target isn't hot. So it starts going toward this not hot goal.
				{
					screen -> PrintfLine(DriverStationLCD::kUser_Line4,"Left Position Not Hot");
					// These DEFINITELY need to be tested. All of them. Forreal.
					turnRight();
					driveForward();
					Wait(4);
					stopDriving();
					//autonomousCatapultRelease();
				}		
			}
			/**CENTER POSITION**/
			else if ((leftPositionSwitch.Get() == 0) && (rightPositionSwitch.Get() == 0)) // Left switch off and right switch off
			{
				screen -> PrintfLine(DriverStationLCD::kUser_Line1,"Middle Position:R"); // Middle position and facing 			
				if ((particleOneOrientation > 0 && particleOneOrientation < 10) || (particleTwoOrientation > 0 && particleTwoOrientation < 10)) // The target should be hot. Now it goes to the other goal.
					/* Theoretically particle 1 or 2 should register as exactly 0 (the particle is horizontal). We can edit these later. */
				{
					screen -> PrintfLine(DriverStationLCD::kUser_Line4,"Middle Position Hot");
					// These DEFINITELY need to be tested. All of them. Forreal.
					turnLeftMore();
					driveForward();
					Wait(3); 
					stopDriving();
					autonomousCatapultRelease();
				}
				else // The target isn't hot. So it starts going toward this not hot goal.
				{
					screen -> PrintfLine(DriverStationLCD::kUser_Line4,"Middle Position Not Hot");
					// These DEFINITELY need to be tested. All of them. Forreal.
					driveForward();
					Wait(3);
					stopDriving();
					autonomousCatapultRelease();
				}
			}
			/** RIGHT POSITION**/
			else if ((leftPositionSwitch.Get() == 1) && (rightPositionSwitch.Get() == 1))
			{
				screen -> PrintfLine(DriverStationLCD::kUser_Line1,"Middle Position:R"); // Middle position and facing
				if ((particleOneOrientation > 0 && particleOneOrientation < 10) || (particleTwoOrientation > 0 && particleTwoOrientation < 10)) // The target should be hot. Now it goes to the other goal.
					/* Theoretically particle 1 or 2 should register as exactly 0 (the particle is horizontal). We can edit these later. */
					{
						screen -> PrintfLine(DriverStationLCD::kUser_Line4,"Middle Position Hot");
						// These DEFINITELY need to be tested. All of them. Forreal.
						turnLeftMore();
						driveForward();
						Wait(3); 
						stopDriving();
						autonomousCatapultRelease();
					}
					else // The target isn't hot. So it starts going toward this not hot goal.
					{
						screen -> PrintfLine(DriverStationLCD::kUser_Line4,"Middle Position Not Hot");
						// These DEFINITELY need to be tested. All of them. Forreal.
						driveForward();
						Wait(3);
						stopDriving();
						autonomousCatapultRelease();
					}
			}
			else if (((leftPositionSwitch.Get()) == 1) && ((rightPositionSwitch.Get()) == 0)) // Left switch off and  switch on
			{
				screen -> PrintfLine(DriverStationLCD::kUser_Line1,"Right Position"); //  position and facing forward
				if ((particleOneOrientation > 0 && particleOneOrientation < 10) || ((particleTwoOrientation > 0) && (particleTwoOrientation < 10))) // The target should be hot. Now it goes to the other goal.
					/* Theoretically particle 1 or 2 should register as exactly 0 (the particle is horizontal). We can edit these later. */
				{
					screen -> PrintfLine(DriverStationLCD::kUser_Line4,"Right Position Hot");
					// These DEFINITELY need to be tested. All of them. Forreal.
					turnLeft();
					driveForward();
					Wait(3);
					stopDriving();
					autonomousCatapultRelease();
				}
				else // The target isn't hot. So it starts going toward this not hot goal.
				{
					screen -> PrintfLine(DriverStationLCD::kUser_Line4, "Right Position Not Hot");
					// These DEFINITELY need to be tested. All of them. Forreal.
					driveForward();
					Wait(3);
					stopDriving();
					autonomousCatapultRelease();
				}
			}
			counter++;
			screen -> PrintfLine(DriverStationLCD::kUser_Line5,"R: %f L: %f)", rightFront.Get(), leftFront.Get());
			screen -> PrintfLine(DriverStationLCD::kUser_Line6,"Counter %d", counter);
			screen->UpdateLCD();
		}
		compressor.Stop();
	}
コード例 #14
0
ファイル: ImageBase.cpp プロジェクト: FRCTeam1967/FRCTeam1967
/**
 * Frees memory associated with an ImageBase.
 * Destructor frees the imaq image allocated with the class.
 */
ImageBase::~ImageBase()
{
	if(m_imaqImage)
		imaqDispose(m_imaqImage);
}
コード例 #15
0
	void Autonomous()
	{
		DriverStationLCD *screen = DriverStationLCD::GetInstance(); 
		while ((IsAutonomous()))
		{
			HSLImage* imgpointer; // declares an image container as an HSL (hue-saturation-luminence) image
			imgpointer = camera.GetImage();	//tells camera to capture image
			backpack.Set(Relay::kForward); //turns ringlight on
			BinaryImage* binIMG = NULL;	// declares a container to hold a binary image
			binIMG = imgpointer -> ThresholdHSL(0, 255, 0, 255, 235, 255);	// thresholds HSL image and places in the binary image container
			delete imgpointer;	// deletes the HSL image to free up memory on the cRIO
			Image* Kirby = imaqCreateImage(IMAQ_IMAGE_U8, 0); //create 8 bit image
			Image* KirbyTwo = imaqCreateImage(IMAQ_IMAGE_U8, 0); // creates the second 8-bit image that we can use separately for counting particles. 
																 // (The first image gets eaten by the measureparticle function)
			float pLower = 175; // min height of rectangle for comparison
			float pUpper = 500;	// max height of rectangle for comparison
			int criteriaCount = 1; // number of elements to include/exclude at a time
			int rejectMatches = 1;	// when set to true, particles that do not meet the criteria are discarded
			int connectivity = 1;	// declares connectivity value as 1; so corners are not ignored
			int Polturgust3000;	// removes small blobs
			int borderSetting;	// variable to store border settings, limit for rectangle
			int cloningDevice; // we create another image because the ParticleMeasuring steals the image from particlecounter
			int borderSize = 1;  // border for the camera frame (if you don't put this, DriverStation gets mad at you)
			ParticleFilterCriteria2 particleCriteria;	
			ParticleFilterOptions2 particleFilterOptions;
			int numParticles;
			particleCriteria.parameter = IMAQ_MT_AREA; //The Morphological measurement we use
			particleCriteria.lower = pLower; // The lower bound of the criteria range
			particleCriteria.upper = pUpper; // The upper bound of the criteria range
			particleCriteria.calibrated = FALSE; // We aren't calibrating to real world measurements. We don't need this.
			particleCriteria.exclude = TRUE; // Remove all particles that aren't in specific pLower and pUpper range
			particleFilterOptions.rejectMatches = rejectMatches; // Set to 1 above, so images that do not meet the criteria are discarded
			particleFilterOptions.rejectBorder = 0; // Set to 0 over here so border images are not discarded
			particleFilterOptions.connectivity8 = connectivity; // Sets the image image to 8 bit
			
			Polturgust3000 = imaqParticleFilter4(Kirby, binIMG -> GetImaqImage(), &particleCriteria, criteriaCount, &particleFilterOptions, NULL, &numParticles); //The Particle Filter Function we use. (The ones before it are outdated)
			borderSetting = imaqSetBorderSize(Kirby, borderSize); // Sets a border size
			cloningDevice =  imaqDuplicate(KirbyTwo, Kirby); //Officially creating a duplicate of the first image to count the number of particles.
			delete binIMG; //Deletes the Binary image
			int ParticleCounter;	// stores number of particles
			int* countparticles; // stores the number of particles for the measure particle function

			ParticleCounter = imaqCountParticles(Kirby, TRUE, countparticles); // Counts the number of particles to be sent off later to the MeasureParticle function. Then it gets eaten by the measureparticle function
			int TinyRuler; // TRULY ARBITRARY name of the first measuring particle function (specifically for particle #1)
			int BabyYardstick; // TRULY ARBITRARY Name of the second measuring particle function (specifically for particle #2)
			double* unowidth; // TRULY ARBITRARY name of the first particle it find
			double* doswidth; // TRULY ARBITRARY name of the second particle it finds

			TinyRuler = imaqMeasureParticle(Kirby, 0, FALSE, IMAQ_MT_BOUNDING_RECT_WIDTH, unowidth); // Function of measuring rectangle width is applied to particle 1 (unowidth)
			BabyYardstick = imaqMeasureParticle(Kirby, 1, FALSE, IMAQ_MT_BOUNDING_RECT_WIDTH, doswidth); // Function of measuring width is applied to particle 2 (doswidth)

			
			screen->PrintfLine(DriverStationLCD::kUser_Line3,"W1: %f",*unowidth); // Prints the applied information to particle 1. (Rectangle width)
			screen->PrintfLine(DriverStationLCD::kUser_Line4,"W2: %f",*doswidth);
			imaqDispose(Kirby);
			imaqDispose(KirbyTwo);
			if (((togglebuttonOne.Get()) == 0) && ((togglebuttonTwo.Get()) == 1))
			{
				screen -> PrintfLine(DriverStationLCD::kUser_Line1,"Left Position");
				if (*unowidth > 20) // The target should be hot. Now it goes to the other goal.
					// Even this needs to be tested
				{	
					screen -> PrintfLine(DriverStationLCD::kUser_Line6,"Left Position Hot");
					// These DEFINITELY need to be tested. All of them. Forreal.
					turnRight();
					driveForward();
					Wait(3); 
					stopDriving();
					shootCatapult();
				}
				else // The target isn't hot. So it starts going toward this not hot goal.
				{
					screen -> PrintfLine(DriverStationLCD::kUser_Line6,"Left Position Not Hot");
					// These DEFINITELY need to be tested. All of them. Forreal.
					driveForward();
					Wait(3);
					stopDriving();
					shootCatapult();
				}
			}
			//both on
			else if (((togglebuttonOne.Get()) == 1) && ((togglebuttonTwo.Get()) == 1))
			{
				screen -> PrintfLine(DriverStationLCD::kUser_Line1,"Middle Position");
				if (*unowidth > 20) // The target should be hot. Now it goes to the other goal.
				{
					screen -> PrintfLine(DriverStationLCD::kUser_Line6,"Middle Position Hot");
					// These DEFINITELY need to be tested. All of them. Forreal.
					turnLeftMore();
					driveForward();
					Wait(3); 
					stopDriving();
					shootCatapult();
				}
				else if (((togglebuttonOne.Get()) == 0) && ((togglebuttonTwo.Get()) == 0))
				{
					screen -> PrintfLine(DriverStationLCD::kUser_Line1,"Middle Position");
					if (*unowidth > 20) // The target should be hot. Now it goes to the other goal.
					{
						screen -> PrintfLine(DriverStationLCD::kUser_Line6,"Middle Position Hot");
						// These DEFINITELY need to be tested. All of them. Forreal.
						turnRightMore();
						driveForward();
						Wait(3); 
						stopDriving();
						shootCatapult();
					}
					else // The target isn't hot. So it starts going toward this not hot goal.
					{
						screen -> PrintfLine(DriverStationLCD::kUser_Line6,"Middle Position Not Hot");
						// These DEFINITELY need to be tested. All of them. Forreal.
						driveForward();
						Wait(3);
						stopDriving();
						shootCatapult();
						driveForward();
						Wait(3);
						stopDriving();
					}
				}
				//Left button on && right off
				else if (((togglebuttonOne.Get()) == 1) && ((togglebuttonTwo.Get()) == 0))
				{
					screen -> PrintfLine(DriverStationLCD::kUser_Line6,"Right Position");
					if (*unowidth > 20) // The target should be hot. Now it goes to the other goal.
					{
						screen -> PrintfLine(DriverStationLCD::kUser_Line6,"Right Position Hot");
						// These DEFINITELY need to be tested. All of them. Forreal.
						turnLeft();
						driveForward();
						Wait(3); 
						stopDriving();
						shootCatapult();
					}
					else // The target isn't hot. So it starts going toward this not hot goal.
					{
						screen -> PrintfLine(DriverStationLCD::kUser_Line6,"Right Position Not Hot");
						// These DEFINITELY need to be tested. All of them. Forreal.
						driveForward();
						Wait(3);
						stopDriving();
						shootCatapult();
					}
				}
			Wait(0.005);
			screen -> UpdateLCD();
			}
		}
	}
コード例 #16
0
	void OperatorControl(void)
	{
		myRobot.SetSafetyEnabled(false);
		AxisCamera &camera = AxisCamera::GetInstance("10.28.53.11");
		camera.WriteResolution(AxisCamera::kResolution_320x240);
		camera.WriteRotation(AxisCamera::kRotation_180);//Flip image upside-down.
		camera.WriteCompression(80);//Compresses the image(?)
		camera.WriteBrightness(50);//Sets the brightness to 80 on a scale from 0-100
		DriverStationLCD *screen = DriverStationLCD::GetInstance();
		int count = 0;
		while(IsOperatorControl())
		{
			screen->UpdateLCD();
			count++;
			HSLImage* imgpointer;		//declares a new hue saturation lum image
			imgpointer = camera.GetImage();  //grabs an image to initialize that image
			//imaqCreateImage(IMAQ_IMAGE_U8,) 
			//imaqCast(NULL, imgpointer, IMAQ_IMAGE_U8, NULL, -1);
			BinaryImage* binImg = NULL;	//declares a new binary image
			
			
			//ThresholdHSL changes our regular image into a binary image.
			/*hueLow Low value for hue  
			hueHigh High value for hue  
			saturationLow Low value for saturation  
			saturationHigh High value for saturation  
			luminenceLow Low value for luminence  
			luminenceHigh High value for luminence   
			 */
			binImg = imgpointer->ThresholdHSL(1, 255, 1, 255, 230, 255);
			
			//Saves the image to a temp directory
			binImg->Write("/tmp/thresh.jpg");
			
			//Writes the binary image to disk
			
			imaqWriteFile(binImg->GetImaqImage(), "/tmp/thresh2.jpg", NULL);
			
			delete imgpointer;
			Image* Convex = imaqCreateImage(IMAQ_IMAGE_U8, 0);
			int returnvalue;
			returnvalue = imaqConvexHull(Convex, binImg->GetImaqImage(), TRUE);
			
	//		imaqWriteFile(Convex, "/tmp/convex.jpg", NULL); 
		
			delete binImg;
	//		screen->PrintfLine(DriverStationLCD::kUser_Line4,"convex is %d",returnvalue);
			screen->UpdateLCD();
			float lookuptable[256];
			lookuptable[0] = 0;
			lookuptable[1] = 65535;
			
			//Converts image to 16 bit, then back to 8 bit.
			Image* cast = imaqCreateImage(IMAQ_IMAGE_U16, 0);
			imaqCast(cast, Convex, IMAQ_IMAGE_U16, lookuptable, 0);
			imaqDispose(Convex);
			Image* bitcast = imaqCreateImage(IMAQ_IMAGE_U8, 0);
			imaqCast(bitcast, cast, IMAQ_IMAGE_U8, NULL, 0);
			imaqDispose(cast);
	//		screen->PrintfLine(DriverStationLCD::kUser_Line3,"det %d", imaqGetLastError());//Notifies the user
			imaqWriteFile(bitcast, "/tmp/bitcast.jpg", NULL);
			
			//Image* SuperSize = im
			//imaqCreateImage(IMAQ_IMAGE_U8, 2240);
			//int returnvalue2;
			//returnvalue2 = imaqSizeFilter(SuperSize, Convex, TRUE, 1, IMAQ_KEEP_LARGE, NULL); 
			//screen->UpdateLCD();
			//imaqDispose (Convex);
//			ROI *roi;
//			Rect rectangle;
//			rectangle.top = 0;
//			rectangle.left = 0;
//			rectangle.width = 320;
//			rectangle.height = 120;
//			imaqAddRectContour(roi,rectangle);
			
			static RectangleDescriptor rectangleDescriptor = 
			{
				30, 	// minWidth (All values are estimated)
				200, 	// maxWidth
				20, 	// minHeight
				200		// maxHeight
			};
		
			static CurveOptions curveOptions = //extraction mode specifies what the VI identifies curves in the image. curve options are all the  
			{	
				IMAQ_NORMAL_IMAGE,	// extractionMode
				75, 				// threshold
				IMAQ_NORMAL, 		// filterSize
				25, 				// minLength
				15, 				// rowStepSize 
				15, 				// columnStepSize
				10, 				// maxEndPointGap
				FALSE,				// onlyClosed
				FALSE				// subpixelAccuracy
			};
			static ShapeDetectionOptions shapeOptions = 
			{		
				IMAQ_GEOMETRIC_MATCH_ROTATION_INVARIANT,	// mode
				NULL,			// angle ranges
				0,				// num angle ranges
				{75, 125},		// scale range
				300				// minMatchScore
			};
			
			int matches = 0;
			//double highscore = 0;
			//int highestindex = -1;
			float difference = 0;
			float time = 0;
			float average = 0;
			double y = 0;
			
			
			//The big important line of code that does important stuff
			RectangleMatch* recmatch = imaqDetectRectangles(bitcast, &rectangleDescriptor, &curveOptions, &shapeOptions, NULL, &matches);

//			DashboardDataSender *dds;
//			dds = new DashboardDataSender;

			//screen->PrintfLine(DriverStationLCD::kUser_Line3,"det %d", imaqGetLastError());
			//screen->PrintfLine(DriverStationLCD::kUser_Line4,"Matches: %d",matches);//Notifies the user
			screen->PrintfLine(DriverStationLCD::kUser_Line1,"Matches: %i",matches);//Notifies the user
			screen->UpdateLCD();
			
			/*for(int i = 0; i < matches; i++)
			{
				//screen->PrintfLine((DriverStationLCD::Line)(i+1),"%i,%i,%i",recmatch[i].height,recmatch[i].width,recmatch[i].score);
				if(recmatch[i].score > highscore)
				{
					highscore = recmatch[i].score;
					highestindex = i;
				}
				screen->PrintfLine(DriverStationLCD::kUser_Line1,"score %i, i %i", recmatch[i].score, i);
				screen->UpdateLCD();
			}*/
			average = (recmatch->corner[1].x + recmatch->corner[3].x)/2;
			y = (472/(recmatch->height-4));
			screen->PrintfLine(DriverStationLCD::kUser_Line5,"%f",average);
			screen->PrintfLine(DriverStationLCD::kUser_Line3," %f",distance(recmatch->height));
			//screen->PrintfLine(DriverStationLCD::kUser_Line5,"%f,%f",recmatch->height, y);
			screen->PrintfLine(DriverStationLCD::kUser_Line6,"%f,%f",ceil(recmatch->corner[1].x),ceil(recmatch->corner[3].x));
			screen->UpdateLCD();
			//screen->PrintfLine(DriverStationLCD::kUser_Line6,"%d, %d, %d, %d",recmatch->corner[1].x,recmatch->corner[2].x,recmatch->corner[3].x,recmatch->corner[4].x);
			//screen->PrintfLine(DriverStationLCD::kUser_Line5,"%d, %d",recmatch->height,recmatch->width);
			if(average == 0)
			{
				screen->PrintfLine(DriverStationLCD::kUser_Line1,"Image Not Found");
			}
			else if(average < 145)
			{
				difference = (160 - average);
				time = difference*0.0062;
				vic.Set(0.1);
				Wait(time);
				vic.Set(0.0);
				screen->PrintfLine(DriverStationLCD::kUser_Line1,"Less!");
				screen->UpdateLCD();
			}
			else if (average > 175)
			{
				difference = (average - 160);
				time = difference*0.0062;
				vic.Set(-0.1);
				Wait(time);
				vic.Set(0.0);
				screen->PrintfLine(DriverStationLCD::kUser_Line1,"More!");
				screen->UpdateLCD();
			}
			else
			{
				vic.Set(0);
				screen->PrintfLine(DriverStationLCD::kUser_Line1,"Perfection!");
				screen->UpdateLCD();
			}
			screen->PrintfLine(DriverStationLCD::kUser_Line2,"Time: %f",time);
			screen->PrintfLine(DriverStationLCD::kUser_Line4,"difference %f",difference);

		//	screen->PrintfLine(DriverStationLCD::kUser_Line2,"Score %i, Index %i", highscore, highestindex);
	/*		if(matches > 0)
			{
				int counter = 0;
				while (counter < 20)	
				{
					average = (recmatch[highestindex].corner[1].x + recmatch[highestindex].corner[2].x + recmatch[highestindex].corner[3].x +recmatch[highestindex].corner[4].x)/4;
					average2 = (recmatch[highestindex].corner[1].y + recmatch[highestindex].corner[2].y + recmatch[highestindex].corner[3].y +recmatch[highestindex].corner[4].y)/4;
				//	screen->PrintfLine(DriverStationLCD::kUser_Line5,"Center = %f, %f",average, average2);
					screen->UpdateLCD();
					if (average > 170)
					{
						vic.Set(-0.1);
						//screen->PrintfLine(DriverStationLCD::kUser_Line1,"Left %f",vic.Get());
						//screen->UpdateLCD();		
					}
					else if (average < 150)
					{
						vic.Set(0.1);
						//screen->PrintfLine(DriverStationLCD::kUser_Line1,"Right %f",vic.Get());
						//screen->UpdateLCD();
					}
					else
					{
						counter = 20;	
						vic.Set(0);
				//		screen->PrintfLine(DriverStationLCD::kUser_Line6,"Not Mallory! %f",vic.Get());
						screen->UpdateLCD();
					}
					counter++a;
				}
				*/
	//			imaqWriteFile(cast, "/tmp/linedetect.jpg", NULL);
				
//			}
/*			else
			{
				vic.Set(0);
			//	screen->PrintfLine(DriverStationLCD::kUser_Line6,"Not Mallory! %f",vic.Get());
				screen->UpdateLCD();
			}*/
			imaqDispose(bitcast);
			imaqDispose(recmatch);
			//imaqDispose(roi);
			vic.Set(0);
		}

	}