/* Constructor, in which all calibration parameters * and auxiliary variables, flags and lists are initilized */ public CalibrationAssistant() { // _imgQualityExaminer = new BackgroundWorker() { WorkerReportsProgress = true, WorkerSupportsCancellation = true }; _imgQualityExaminer.DoWork += _imgQualityExaminer_DoWork; _imgQualityExaminer.ProgressChanged += _imgQualityExaminer_ProgressChanged; _imgQualityExaminer.RunWorkerCompleted += _imgQualityExaminer_RunWorkerCompleted; _addImagTasks = new List<string>(); _imageTaskTimer = new System.Windows.Forms.Timer(); _imageTaskTimer.Tick += _imageTaskTimer_Tick; CalibData = new ArrayList(15); mReferenceIndex = -1; mDescrFileName = "caltab_30mm.descr"; mCalibValid = false; mCanCalib = true; mAtImgCoord = false; mReferenceImage = new HImage(); mSimulatedImage = new HImage(); mFilterSize = resetFilterSize; mMarkThresh = resetMarkThresh; mMinMarkDiam = resetMinMarkDiam; mInitThresh = resetInitThresh; mThreshDecr = resetThreshDecr; mMinThresh = resetMinThresh; mSmoothing = resetSmoothing; mMinContLength = resetMinContL; mMaxMarkDiam = resetMaxMarkDiam; mWarnLevel = 70; mImageTests = QUALITY_ISSUE_TEST_ALL; mSequenceTests = QUALITY_ISSUE_TEST_ALL; mSeqQualityList = new ArrayList(15); procedure = new QualityProcedures(); mThickness = 630; // micrometer mCameraType = CAMERA_TYP_AREA_SCAN_DIV; mCellWidth = 8300.0; // nm mCellHeight = 8300.0; // nm mFocalLength = 8000; // micrometer isTelecentric = false; mKappa = 0.0; mK1 = 0.0; mK2 = 0.0; mK3 = 0.0; mP1 = 0.0; mP2 = 0.0; mMotionVx = 0.0; mMotionVy = 500.0; mMotionVz = 0.0; NotifyCalibObserver = new CalibDelegate(dummy); }
/// <summary> /// Determine s(or updates) the basic information for this /// calibration image, which are the values for the region /// plate, the center marks, and the estimated pose. /// The flag <c>mPlateStatus</c> describes the evaluation /// of the computation process. /// If desired the quality assessment can be recalculated /// as well. /// </summary> /// <param name="updateQuality"> /// Triggers the recalculation of the quality assessment for /// this calibration image /// </param> public void UpdateCaltab(bool updateQuality) { HTuple worldX, worldY; HTuple unit = new HTuple("m"); bool failed = false; QualityProcedures proc = new QualityProcedures(); string descrFile; HTuple startCamp; ErrorMessage = ""; _mCaltabRegion.Dispose(); _mMarkCenter.Dispose(); _mEstimatedWCS.Dispose(); //reset this variable _mMarkCenterRows = new HTuple(); PlateStatus = CalibrationAssistant.PS_NOT_FOUND; descrFile = _mAssistant.getDesrcFile(); try { _mCaltabRegion = _mImage.FindCaltab(descrFile, (int)_mAssistant.mFilterSize, (int)_mAssistant.mMarkThresh, (int)_mAssistant.mMinMarkDiam); PlateStatus = CalibrationAssistant.PS_MARKS_FAILED; //-- Quality issue measurements -- if (updateQuality) { _mQualityIssuesList.Clear(); failed = _mAssistant.testQualityIssues(this); } startCamp = _mAssistant.getCameraParams(this); _mMarkCenterRows = _mImage.FindMarksAndPose(_mCaltabRegion, descrFile, startCamp, (int)_mAssistant.mInitThresh, (int)_mAssistant.mThreshDecr, (int)_mAssistant.mMinThresh, _mAssistant.mSmoothing, _mAssistant.mMinContLength, _mAssistant.mMaxMarkDiam, out _mMarkCenterCols, out _mEstimatedPose); _mMarkCenter.GenCrossContourXld(_mMarkCenterRows, _mMarkCenterCols, new HTuple(6.0), 0.785398); if (failed) { _mAssistant.addQualityIssue(this, CalibrationAssistant.QUALITY_ISSUE_FAILURE, 0.0); } HOperatorSet.ImagePointsToWorldPlane(startCamp, _mEstimatedPose, _mMarkCenterRows, _mMarkCenterCols, unit, out worldX, out worldY); _mEstimatedPlateSize = HMisc.DistancePp(worldY[0].D, worldX[0].D, worldY[1].D, worldX[1].D); _mEstimatedPlateSize *= 10.0; proc.get_3d_coord_system(_mImage, out _mEstimatedWCS, startCamp, _mEstimatedPose, new HTuple(_mEstimatedPlateSize / 2.0)); PlateStatus = _mQualityIssuesList.Count > 0 ? CalibrationAssistant.PS_QUALITY_ISSUES : CalibrationAssistant.PS_OK; // "Quality Issues found": "OK"; CanCalibFlag = 0; } catch (HOperatorException e) { this.ErrorMessage = e.Message; CanCalibFlag = 1; /* if exception was raised due to lack of memory, * forward the error to the calling method */ if (e.Message.IndexOf("not enough") != -1) { throw (e); } } }
/// <summary> /// Tests different quality features for the calibration image /// <c>cImg</c> /// </summary> /// <returns> /// Returns a value indicating the success or failure /// of the quality assessment /// </returns> public bool testQualityIssues(CalibImage cImg) { ArrayList qList; HObject markContours; HObject plateRegion; HImage mImg; HTuple score, score2, contrast; int numRegions, numContours; bool qualityFailure; mImg = cImg.GetImage(); qList = cImg.GetQualityIssueList(); procedure = new QualityProcedures(); contrast = new HTuple(); qualityFailure = false; // DescriptionFileName = mDescrFileName; ; try { procedure.find_caltab_edges(mImg, out plateRegion, out markContours, new HTuple(mDescrFileName)); numRegions = plateRegion.CountObj(); numContours = markContours.CountObj(); if (mImageTests < QUALITY_ISSUE_TEST_NONE) { if (numRegions == 0) { qualityFailure = true; } else { procedure.eval_caltab_overexposure(mImg, plateRegion, out score); addQualityIssue(qList, QUALITY_ISSUE_IMG_EXPOSURE, score.D); } if (numContours == 0) { qualityFailure = true; } else { procedure.eval_caltab_contrast_homogeneity(mImg, markContours, out contrast, out score, out score2); addQualityIssue(qList, QUALITY_ISSUE_IMG_CONTRAST, score.D); addQualityIssue(qList, QUALITY_ISSUE_IMG_HOMOGENEITY, score2.D); procedure.eval_caltab_size(mImg, plateRegion, markContours, out score); addQualityIssue(qList, QUALITY_ISSUE_IMG_CALTAB_SIZE, score.D); } if (mImageTests == QUALITY_ISSUE_TEST_ALL) { procedure.eval_caltab_focus(mImg, markContours, contrast, out score); addQualityIssue(qList, QUALITY_ISSUE_IMG_FOCUS, score.D); } } } catch (HOperatorException e) { throw (e); } return qualityFailure; }
/// <summary> /// Determine s(or updates) the basic information for this /// calibration image, which are the values for the region /// plate, the center marks, and the estimated pose. /// The flag <c>mPlateStatus</c> describes the evaluation /// of the computation process. /// If desired the quality assessment can be recalculated /// as well. /// </summary> /// <param name="updateQuality"> /// Triggers the recalculation of the quality assessment for /// this calibration image /// </param> public void UpdateCaltab(bool updateQuality) { HTuple worldX, worldY; HTuple unit = new HTuple("m"); bool failed = false; QualityProcedures proc = new QualityProcedures(); string descrFile; HTuple startCamp; ErrorMessage = ""; _mCaltabRegion.Dispose(); _mMarkCenter.Dispose(); _mEstimatedWCS.Dispose(); //reset this variable _mMarkCenterRows = new HTuple(); PlateStatus = CalibrationAssistant.PS_NOT_FOUND; descrFile = _mAssistant.getDesrcFile(); try { _mCaltabRegion = _mImage.FindCaltab(descrFile, (int)_mAssistant.mFilterSize, (int)_mAssistant.mMarkThresh, (int)_mAssistant.mMinMarkDiam); PlateStatus = CalibrationAssistant.PS_MARKS_FAILED; //-- Quality issue measurements -- if (updateQuality) { _mQualityIssuesList.Clear(); failed = _mAssistant.testQualityIssues(this); } startCamp = _mAssistant.getCameraParams(this); _mMarkCenterRows = _mImage.FindMarksAndPose(_mCaltabRegion, descrFile, startCamp, (int)_mAssistant.mInitThresh, (int)_mAssistant.mThreshDecr, (int)_mAssistant.mMinThresh, _mAssistant.mSmoothing, _mAssistant.mMinContLength, _mAssistant.mMaxMarkDiam, out _mMarkCenterCols, out _mEstimatedPose); _mMarkCenter.GenCrossContourXld(_mMarkCenterRows, _mMarkCenterCols, new HTuple(6.0), 0.785398); if (failed) _mAssistant.addQualityIssue(this, CalibrationAssistant.QUALITY_ISSUE_FAILURE, 0.0); HOperatorSet.ImagePointsToWorldPlane(startCamp, _mEstimatedPose, _mMarkCenterRows, _mMarkCenterCols, unit, out worldX, out worldY); _mEstimatedPlateSize = HMisc.DistancePp(worldY[0].D, worldX[0].D, worldY[1].D, worldX[1].D); _mEstimatedPlateSize *= 10.0; proc.get_3d_coord_system(_mImage, out _mEstimatedWCS, startCamp, _mEstimatedPose, new HTuple(_mEstimatedPlateSize / 2.0)); PlateStatus = _mQualityIssuesList.Count > 0 ? CalibrationAssistant.PS_QUALITY_ISSUES : CalibrationAssistant.PS_OK; // "Quality Issues found": "OK"; CanCalibFlag = 0; } catch (HOperatorException e) { this.ErrorMessage = e.Message; CanCalibFlag = 1; /* if exception was raised due to lack of memory, * forward the error to the calling method */ if (e.Message.IndexOf("not enough") != -1) throw (e); } }