int arDetectMarkerLite( ARUint8 *dataPtr, int thresh, ARMarkerInfo **marker_info, int *marker_num, ARMarkerInfo2 **m_info2) { ARInt16 *limage; int label_num; int *area, *clip, *label_ref; double *pos; int i; *marker_num = 0; limage = arLabeling( dataPtr, thresh, &label_num, &area, &pos, &clip, &label_ref ); if( limage == 0 ) return -1; marker_info2 = arDetectMarker2( limage, label_num, label_ref, area, pos, clip, AR_AREA_MAX, AR_AREA_MIN, 1.0, &wmarker_num); if( marker_info2 == 0 ) return -1; wmarker_info = arGetMarkerInfo( dataPtr, marker_info2, &wmarker_num ); if( wmarker_info == 0 ) return -1; for( i = 0; i < wmarker_num; i++ ) { if( wmarker_info[i].cf < 0.5 ) wmarker_info[i].id = -1; } *marker_num = wmarker_num; *marker_info = wmarker_info; if(m_info2 != NULL){ *m_info2 = marker_info2; } return 0; }
int arsDetectMarkerLite( ARUint8 *dataPtr, int thresh, ARMarkerInfo **marker_info, int *marker_num, int LorR ) { ARInt16 *limage; int label_num; int *area, *clip, *label_ref; double *pos; int i; *marker_num = 0; limage = arsLabeling( dataPtr, thresh, &label_num, &area, &pos, &clip, &label_ref, LorR ); if( limage == 0 ) return -1; marker_info2 = arDetectMarker2( limage, label_num, label_ref, area, pos, clip, AR_AREA_MAX, AR_AREA_MIN, 1.0, &wmarker_num); if( marker_info2 == 0 ) return -1; wmarker_info = arsGetMarkerInfo( dataPtr, marker_info2, &wmarker_num, LorR ); if( wmarker_info == 0 ) return -1; for( i = 0; i < wmarker_num; i++ ) { if( wmarker_info[i].cf < AR_CF_THRESHOLD ) wmarker_info[i].id = -1; } *marker_num = wmarker_num; *marker_info = wmarker_info; return 0; }
int arDetectMarker( ARHandle *arHandle, ARUint8 *dataPtr ) { ARdouble rarea, rlen, rlenmin; ARdouble diff, diffmin; int cid, cdir; int i, j, k; int detectionIsDone = 0; #if DEBUG_PATT_GETID cnt = 0; #endif arHandle->marker_num = 0; if (arHandle->arLabelingThreshMode == AR_LABELING_THRESH_MODE_AUTO_BRACKETING) { if (arHandle->arLabelingThreshAutoIntervalTTL > 0) { arHandle->arLabelingThreshAutoIntervalTTL--; } else { int thresholds[3]; int marker_nums[3]; thresholds[0] = arHandle->arLabelingThresh + arHandle->arLabelingThreshAutoBracketOver; if (thresholds[0] > 255) thresholds[0] = 255; thresholds[1] = arHandle->arLabelingThresh - arHandle->arLabelingThreshAutoBracketUnder; if (thresholds[1] < 0) thresholds[1] = 0; thresholds[2] = arHandle->arLabelingThresh; for (i = 0; i < 3; i++) { if (arLabeling(dataPtr, arHandle->xsize, arHandle->ysize, arHandle->arPixelFormat, arHandle->arDebug, arHandle->arLabelingMode, thresholds[i], arHandle->arImageProcMode, &(arHandle->labelInfo), NULL) < 0) return -1; if (arDetectMarker2(arHandle->xsize, arHandle->ysize, &(arHandle->labelInfo), arHandle->arImageProcMode, AR_AREA_MAX, AR_AREA_MIN, AR_SQUARE_FIT_THRESH, arHandle->markerInfo2, &(arHandle->marker2_num)) < 0) return -1; if (arGetMarkerInfo(dataPtr, arHandle->xsize, arHandle->ysize, arHandle->arPixelFormat, arHandle->markerInfo2, arHandle->marker2_num, arHandle->pattHandle, arHandle->arImageProcMode, arHandle->arPatternDetectionMode, &(arHandle->arParamLT->paramLTf), arHandle->pattRatio, arHandle->markerInfo, &(arHandle->marker_num), arHandle->matrixCodeType) < 0) return -1; marker_nums[i] = arHandle->marker_num; } if (arHandle->arDebug == AR_DEBUG_ENABLE) ARLOGe("Auto threshold (bracket) marker counts -[%3d: %3d] [%3d: %3d] [%3d: %3d]+.\n", thresholds[1], marker_nums[1], thresholds[2], marker_nums[2], thresholds[0], marker_nums[0]); // If neither of the bracketed values was superior, then change the size of the bracket. if (marker_nums[0] <= marker_nums[2] && marker_nums[1] <= marker_nums[2]) { if (arHandle->arLabelingThreshAutoBracketOver < arHandle->arLabelingThreshAutoBracketUnder) { arHandle->arLabelingThreshAutoBracketOver++; } else if (arHandle->arLabelingThreshAutoBracketOver > arHandle->arLabelingThreshAutoBracketUnder) { arHandle->arLabelingThreshAutoBracketUnder++; } else { arHandle->arLabelingThreshAutoBracketOver++; arHandle->arLabelingThreshAutoBracketUnder++; } if ((thresholds[2] + arHandle->arLabelingThreshAutoBracketOver) >= 255) arHandle->arLabelingThreshAutoBracketOver = 1; // If the bracket has hit the end of the range, reset it. if ((thresholds[2] - arHandle->arLabelingThreshAutoBracketOver) <= 0) arHandle->arLabelingThreshAutoBracketUnder = 1; // If a bracket has hit the end of the range, reset it. detectionIsDone = 1; } else { arHandle->arLabelingThresh = (marker_nums[0] >= marker_nums[1] ? thresholds[0] : thresholds[1]); int threshDiff = arHandle->arLabelingThresh - thresholds[2]; if (threshDiff > 0) { arHandle->arLabelingThreshAutoBracketOver = threshDiff; arHandle->arLabelingThreshAutoBracketUnder = 1; } else { arHandle->arLabelingThreshAutoBracketOver = 1; arHandle->arLabelingThreshAutoBracketUnder = -threshDiff; } if (arHandle->arDebug == AR_DEBUG_ENABLE) ARLOGe("Auto threshold (bracket) adjusted threshold to %d.\n", arHandle->arLabelingThresh); } arHandle->arLabelingThreshAutoIntervalTTL = arHandle->arLabelingThreshAutoInterval; } } if (!detectionIsDone) { #if !AR_DISABLE_THRESH_MODE_AUTO_ADAPTIVE if (arHandle->arLabelingThreshMode == AR_LABELING_THRESH_MODE_AUTO_ADAPTIVE) { int ret; ret = arImageProcLumaHistAndBoxFilterWithBias(arHandle->arImageProcInfo, dataPtr, AR_LABELING_THRESH_ADAPTIVE_KERNEL_SIZE_DEFAULT, AR_LABELING_THRESH_ADAPTIVE_BIAS_DEFAULT); if (ret < 0) return (ret); ret = arLabeling(arHandle->arImageProcInfo->image, arHandle->arImageProcInfo->imageX, arHandle->arImageProcInfo->imageY, AR_PIXEL_FORMAT_MONO, arHandle->arDebug, arHandle->arLabelingMode, 0, AR_IMAGE_PROC_FRAME_IMAGE, &(arHandle->labelInfo), arHandle->arImageProcInfo->image2); if (ret < 0) return (ret); } else { // !adaptive #endif if (arHandle->arLabelingThreshMode == AR_LABELING_THRESH_MODE_AUTO_MEDIAN || arHandle->arLabelingThreshMode == AR_LABELING_THRESH_MODE_AUTO_OTSU) { // Do an auto-threshold operation. if (arHandle->arLabelingThreshAutoIntervalTTL > 0) { arHandle->arLabelingThreshAutoIntervalTTL--; } else { int ret; unsigned char value; if (arHandle->arLabelingThreshMode == AR_LABELING_THRESH_MODE_AUTO_MEDIAN) ret = arImageProcLumaHistAndCDFAndMedian(arHandle->arImageProcInfo, dataPtr, &value); else ret = arImageProcLumaHistAndOtsu(arHandle->arImageProcInfo, dataPtr, &value); if (ret < 0) return (ret); if (arHandle->arDebug == AR_DEBUG_ENABLE && arHandle->arLabelingThresh != value) ARLOGe("Auto threshold (%s) adjusted threshold to %d.\n", (arHandle->arLabelingThreshMode == AR_LABELING_THRESH_MODE_AUTO_MEDIAN ? "median" : "Otsu"), value); arHandle->arLabelingThresh = value; arHandle->arLabelingThreshAutoIntervalTTL = arHandle->arLabelingThreshAutoInterval; } } if( arLabeling(dataPtr, arHandle->xsize, arHandle->ysize, arHandle->arPixelFormat, arHandle->arDebug, arHandle->arLabelingMode, arHandle->arLabelingThresh, arHandle->arImageProcMode, &(arHandle->labelInfo), NULL) < 0 ) { return -1; } #if !AR_DISABLE_THRESH_MODE_AUTO_ADAPTIVE } #endif if( arDetectMarker2( arHandle->xsize, arHandle->ysize, &(arHandle->labelInfo), arHandle->arImageProcMode, AR_AREA_MAX, AR_AREA_MIN, AR_SQUARE_FIT_THRESH, arHandle->markerInfo2, &(arHandle->marker2_num) ) < 0 ) { return -1; } if( arGetMarkerInfo(dataPtr, arHandle->xsize, arHandle->ysize, arHandle->arPixelFormat, arHandle->markerInfo2, arHandle->marker2_num, arHandle->pattHandle, arHandle->arImageProcMode, arHandle->arPatternDetectionMode, &(arHandle->arParamLT->paramLTf), arHandle->pattRatio, arHandle->markerInfo, &(arHandle->marker_num), arHandle->matrixCodeType ) < 0 ) { return -1; } } // !detectionIsDone // If history mode is not enabled, just perform a basic confidence cutoff. if (arHandle->arMarkerExtractionMode == AR_NOUSE_TRACKING_HISTORY) { confidenceCutoff(arHandle); return 0; } /*------------------------------------------------------------*/ // For all history records, check every identified marker, to see if the position and size of the marker // as recorded in the history record is very similar to one of the identified markers. // If it is, and the history record has a higher confidence value, then use the pattern matching // information (marker ID, confidence, and direction) info from the history instead. for( i = 0; i < arHandle->history_num; i++ ) { rlenmin = 0.5; cid = -1; for( j = 0; j < arHandle->marker_num; j++ ) { rarea = (ARdouble)arHandle->history[i].marker.area / (ARdouble)arHandle->markerInfo[j].area; if( rarea < 0.7 || rarea > 1.43 ) continue; rlen = ( (arHandle->markerInfo[j].pos[0] - arHandle->history[i].marker.pos[0]) * (arHandle->markerInfo[j].pos[0] - arHandle->history[i].marker.pos[0]) + (arHandle->markerInfo[j].pos[1] - arHandle->history[i].marker.pos[1]) * (arHandle->markerInfo[j].pos[1] - arHandle->history[i].marker.pos[1]) ) / arHandle->markerInfo[j].area; if( rlen < rlenmin ) { rlenmin = rlen; cid = j; } } if (cid >= 0) { if (arHandle->arPatternDetectionMode == AR_TEMPLATE_MATCHING_COLOR || arHandle->arPatternDetectionMode == AR_TEMPLATE_MATCHING_MONO || arHandle->arPatternDetectionMode == AR_MATRIX_CODE_DETECTION) { if (arHandle->markerInfo[cid].cf < arHandle->history[i].marker.cf) { arHandle->markerInfo[cid].cf = arHandle->history[i].marker.cf; arHandle->markerInfo[cid].id = arHandle->history[i].marker.id; diffmin = 10000.0 * 10000.0; cdir = -1; for( j = 0; j < 4; j++ ) { diff = 0; for( k = 0; k < 4; k++ ) { diff += (arHandle->history[i].marker.vertex[k][0] - arHandle->markerInfo[cid].vertex[(j+k)%4][0]) * (arHandle->history[i].marker.vertex[k][0] - arHandle->markerInfo[cid].vertex[(j+k)%4][0]) + (arHandle->history[i].marker.vertex[k][1] - arHandle->markerInfo[cid].vertex[(j+k)%4][1]) * (arHandle->history[i].marker.vertex[k][1] - arHandle->markerInfo[cid].vertex[(j+k)%4][1]); } if( diff < diffmin ) { diffmin = diff; cdir = (arHandle->history[i].marker.dir - j + 4) % 4; } } arHandle->markerInfo[cid].dir = cdir; // Copy the id, cf, and dir back to the appropriate mode-dependent values too. if (arHandle->arPatternDetectionMode == AR_TEMPLATE_MATCHING_COLOR || arHandle->arPatternDetectionMode == AR_TEMPLATE_MATCHING_MONO) { arHandle->markerInfo[cid].idPatt = arHandle->markerInfo[cid].id; arHandle->markerInfo[cid].cfPatt = arHandle->markerInfo[cid].cf; arHandle->markerInfo[cid].dirPatt = arHandle->markerInfo[cid].dir; } else { arHandle->markerInfo[cid].idMatrix = arHandle->markerInfo[cid].id; arHandle->markerInfo[cid].cfMatrix = arHandle->markerInfo[cid].cf; arHandle->markerInfo[cid].dirMatrix = arHandle->markerInfo[cid].dir; } } } else if (arHandle->arPatternDetectionMode == AR_TEMPLATE_MATCHING_COLOR_AND_MATRIX || arHandle->arPatternDetectionMode == AR_TEMPLATE_MATCHING_MONO_AND_MATRIX) { if (arHandle->markerInfo[cid].cfPatt < arHandle->history[i].marker.cfPatt || arHandle->markerInfo[cid].cfMatrix < arHandle->history[i].marker.cfMatrix) { arHandle->markerInfo[cid].cfPatt = arHandle->history[i].marker.cfPatt; arHandle->markerInfo[cid].idPatt = arHandle->history[i].marker.idPatt; arHandle->markerInfo[cid].cfMatrix = arHandle->history[i].marker.cfMatrix; arHandle->markerInfo[cid].idMatrix = arHandle->history[i].marker.idMatrix; diffmin = 10000.0 * 10000.0; cdir = -1; for( j = 0; j < 4; j++ ) { diff = 0; for( k = 0; k < 4; k++ ) { diff += (arHandle->history[i].marker.vertex[k][0] - arHandle->markerInfo[cid].vertex[(j+k)%4][0]) * (arHandle->history[i].marker.vertex[k][0] - arHandle->markerInfo[cid].vertex[(j+k)%4][0]) + (arHandle->history[i].marker.vertex[k][1] - arHandle->markerInfo[cid].vertex[(j+k)%4][1]) * (arHandle->history[i].marker.vertex[k][1] - arHandle->markerInfo[cid].vertex[(j+k)%4][1]); } if( diff < diffmin ) { diffmin = diff; cdir = j; } } arHandle->markerInfo[cid].dirPatt = (arHandle->history[i].marker.dirPatt - cdir + 4) % 4; arHandle->markerInfo[cid].dirMatrix = (arHandle->history[i].marker.dirMatrix - cdir + 4) % 4; } } else return -1; // Unsupported arPatternDetectionMode. } // cid >= 0 } confidenceCutoff(arHandle); // Age all history records (and expire old records, i.e. where count >= 4). for( i = j = 0; i < arHandle->history_num; i++ ) { arHandle->history[i].count++; if( arHandle->history[i].count < 4 ) { if (i != j) arHandle->history[j] = arHandle->history[i]; j++; } } arHandle->history_num = j; // Save current marker info in history. for( i = 0; i < arHandle->marker_num; i++ ) { if( arHandle->markerInfo[i].id < 0 ) continue; // Check if an ARTrackingHistory record already exists for this marker ID. for( j = 0; j < arHandle->history_num; j++ ) { if( arHandle->history[j].marker.id == arHandle->markerInfo[i].id ) break; } if( j == arHandle->history_num ) { // If a pre-existing ARTrackingHistory record was not found, if( arHandle->history_num == AR_SQUARE_MAX ) break; // exit if we've filled all available history slots, arHandle->history_num++; // Otherwise count the newly created record. } arHandle->history[j].marker = arHandle->markerInfo[i]; // Save the marker info. arHandle->history[j].count = 1; // Reset count to indicate info is fresh. } if( arHandle->arMarkerExtractionMode == AR_USE_TRACKING_HISTORY_V2 ) { return 0; } for( i = 0; i < arHandle->history_num; i++ ) { for( j = 0; j < arHandle->marker_num; j++ ) { rarea = (ARdouble)arHandle->history[i].marker.area / (ARdouble)arHandle->markerInfo[j].area; if( rarea < 0.7 || rarea > 1.43 ) continue; rlen = ( (arHandle->markerInfo[j].pos[0] - arHandle->history[i].marker.pos[0]) * (arHandle->markerInfo[j].pos[0] - arHandle->history[i].marker.pos[0]) + (arHandle->markerInfo[j].pos[1] - arHandle->history[i].marker.pos[1]) * (arHandle->markerInfo[j].pos[1] - arHandle->history[i].marker.pos[1]) ) / arHandle->markerInfo[j].area; if( rlen < 0.5 ) break; } if( j == arHandle->marker_num ) { arHandle->markerInfo[arHandle->marker_num] = arHandle->history[i].marker; arHandle->marker_num++; } } return 0; }
int arDetectMarker( ARUint8 *dataPtr, int *thresh, ARMarkerInfo **marker_info, int *marker_num ) { ARInt16 *limage; int label_num; int *area, *clip, *label_ref; double *pos; double rarea, rlen, rlenmin; double diff, diffmin; int cid, cdir; int i, j, k; int _thresh; *marker_num = 0; _thresh = *thresh; for (i = 0; i < 4; ++i) { limage = arLabeling( dataPtr, _thresh, &label_num, &area, &pos, &clip, &label_ref ); if( limage ) { marker_info2 = arDetectMarker2( limage, label_num, label_ref, area, pos, clip, AR_AREA_MAX, AR_AREA_MIN, 1.0, &wmarker_num ); if( marker_info2 ) { wmarker_info = arGetMarkerInfo(dataPtr, marker_info2, &wmarker_num ); /* if( wmarker_info && wmarker_num > 0 ) { */ if( wmarker_info && checkImportantMarkers(wmarker_num, wmarker_info) ) { *thresh = _thresh; break; } } } /* Try some values around the base threshold */ _thresh += ((i+1)*15) * ((i+1)%2 ? 1 : -1); } for( i = 0; i < prev_num; i++ ) { rlenmin = 10.0; cid = -1; for( j = 0; j < wmarker_num; j++ ) { rarea = (double)prev_info[i].marker.area / (double)wmarker_info[j].area; if( rarea < 0.7 || rarea > 1.43 ) continue; rlen = ( (wmarker_info[j].pos[0] - prev_info[i].marker.pos[0]) * (wmarker_info[j].pos[0] - prev_info[i].marker.pos[0]) + (wmarker_info[j].pos[1] - prev_info[i].marker.pos[1]) * (wmarker_info[j].pos[1] - prev_info[i].marker.pos[1]) ) / wmarker_info[j].area; if( rlen < 0.5 && rlen < rlenmin ) { rlenmin = rlen; cid = j; } } if( cid >= 0 && wmarker_info[cid].cf < prev_info[i].marker.cf ) { wmarker_info[cid].cf = prev_info[i].marker.cf; wmarker_info[cid].id = prev_info[i].marker.id; diffmin = 10000.0 * 10000.0; cdir = -1; for( j = 0; j < 4; j++ ) { diff = 0; for( k = 0; k < 4; k++ ) { diff += (prev_info[i].marker.vertex[k][0] - wmarker_info[cid].vertex[(j+k)%4][0]) * (prev_info[i].marker.vertex[k][0] - wmarker_info[cid].vertex[(j+k)%4][0]) + (prev_info[i].marker.vertex[k][1] - wmarker_info[cid].vertex[(j+k)%4][1]) * (prev_info[i].marker.vertex[k][1] - wmarker_info[cid].vertex[(j+k)%4][1]); } if( diff < diffmin ) { diffmin = diff; cdir = (prev_info[i].marker.dir - j + 4) % 4; } } wmarker_info[cid].dir = cdir; } } for( i = 0; i < wmarker_num; i++ ) { /* printf("cf = %g\n", wmarker_info[i].cf); */ if( wmarker_info[i].cf < AR_CF_THRESHOLD ) wmarker_info[i].id = -1; } /*------------------------------------------------------------*/ for( i = j = 0; i < prev_num; i++ ) { prev_info[i].count++; if( prev_info[i].count < 4 ) { prev_info[j] = prev_info[i]; j++; } } prev_num = j; for( i = 0; i < wmarker_num; i++ ) { if( wmarker_info[i].id < 0 ) continue; for( j = 0; j < prev_num; j++ ) { if( prev_info[j].marker.id == wmarker_info[i].id ) break; } prev_info[j].marker = wmarker_info[i]; prev_info[j].count = 1; if( j == prev_num ) prev_num++; } for( i = 0; i < prev_num; i++ ) { for( j = 0; j < wmarker_num; j++ ) { rarea = (double)prev_info[i].marker.area / (double)wmarker_info[j].area; if( rarea < 0.7 || rarea > 1.43 ) continue; rlen = ( (wmarker_info[j].pos[0] - prev_info[i].marker.pos[0]) * (wmarker_info[j].pos[0] - prev_info[i].marker.pos[0]) + (wmarker_info[j].pos[1] - prev_info[i].marker.pos[1]) * (wmarker_info[j].pos[1] - prev_info[i].marker.pos[1]) ) / wmarker_info[j].area; if( rlen < 0.5 ) break; } if( j == wmarker_num ) { wmarker_info[wmarker_num] = prev_info[i].marker; wmarker_num++; } } *marker_num = wmarker_num; *marker_info = wmarker_info; return 0; }
int arsDetectMarker( ARUint8 *dataPtr, int thresh, ARMarkerInfo **marker_info, int *marker_num, int LorR ) { ARInt16 *limage; int label_num; int *area, *clip, *label_ref; double *pos; double rarea, rlen, rlenmin; double diff, diffmin; int cid, cdir; int i, j, k; *marker_num = 0; limage = arsLabeling( dataPtr, thresh, &label_num, &area, &pos, &clip, &label_ref, LorR ); if( limage == 0 ) return -1; marker_info2 = arDetectMarker2( limage, label_num, label_ref, area, pos, clip, AR_AREA_MAX, AR_AREA_MIN, 1.0, &wmarker_num); if( marker_info2 == 0 ) return -1; wmarker_info = arsGetMarkerInfo( dataPtr, marker_info2, &wmarker_num, LorR ); if( wmarker_info == 0 ) return -1; for( i = 0; i < sprev_num[LorR]; i++ ) { rlenmin = 10.0; cid = -1; for( j = 0; j < wmarker_num; j++ ) { rarea = (double)sprev_info[LorR][i].marker.area / (double)wmarker_info[j].area; if( rarea < 0.7 || rarea > 1.43 ) continue; rlen = ( (wmarker_info[j].pos[0] - sprev_info[LorR][i].marker.pos[0]) * (wmarker_info[j].pos[0] - sprev_info[LorR][i].marker.pos[0]) + (wmarker_info[j].pos[1] - sprev_info[LorR][i].marker.pos[1]) * (wmarker_info[j].pos[1] - sprev_info[LorR][i].marker.pos[1]) ) / wmarker_info[j].area; if( rlen < 0.5 && rlen < rlenmin ) { rlenmin = rlen; cid = j; } } if( cid >= 0 && wmarker_info[cid].cf < sprev_info[LorR][i].marker.cf ) { wmarker_info[cid].cf = sprev_info[LorR][i].marker.cf; wmarker_info[cid].id = sprev_info[LorR][i].marker.id; diffmin = 10000.0 * 10000.0; cdir = -1; for( j = 0; j < 4; j++ ) { diff = 0; for( k = 0; k < 4; k++ ) { diff += (sprev_info[LorR][i].marker.vertex[k][0] - wmarker_info[cid].vertex[(j+k)%4][0]) * (sprev_info[LorR][i].marker.vertex[k][0] - wmarker_info[cid].vertex[(j+k)%4][0]) + (sprev_info[LorR][i].marker.vertex[k][1] - wmarker_info[cid].vertex[(j+k)%4][1]) * (sprev_info[LorR][i].marker.vertex[k][1] - wmarker_info[cid].vertex[(j+k)%4][1]); } if( diff < diffmin ) { diffmin = diff; cdir = (sprev_info[LorR][i].marker.dir - j + 4) % 4; } } wmarker_info[cid].dir = cdir; } } for( i = 0; i < wmarker_num; i++ ) { if( wmarker_info[i].cf < AR_CF_THRESHOLD ) wmarker_info[i].id = -1; } j = 0; for( i = 0; i < wmarker_num; i++ ) { if( wmarker_info[i].id < 0 ) continue; sprev_info[LorR][j].marker = wmarker_info[i]; sprev_info[LorR][j].count = 1; j++; } sprev_num[LorR] = j; *marker_num = wmarker_num; *marker_info = wmarker_info; return 0; }
// marker detection using tracking history // AR_TEMPL_FUNC int AR_TEMPL_TRACKER::arDetectMarker(uint8_t *dataPtr, int _thresh, ARMarkerInfo **marker_info, int *marker_num) { int16_t *limage=NULL; int label_num; int *area, *clip, *label_ref; ARFloat *pos; ARFloat rarea, rlen, rlenmin; ARFloat diff, diffmin; int cid, cdir; int i, j, k; trackedCorners.clear(); autoThreshold.reset(); checkImageBuffer(); // FILE* fp = fopen("imgdump.raw", "wb"); // fwrite(dataPtr, 1, 320*240*2, fp); // fclose(fp); *marker_num = 0; for(int numTries = 0;;) { limage = arLabeling(dataPtr, _thresh, &label_num, &area, &pos, &clip, &label_ref); if(limage) { marker_info2 = arDetectMarker2(limage, label_num, label_ref, area, pos, clip, AR_AREA_MAX, AR_AREA_MIN, 1.0, &wmarker_num); assert(wmarker_num <= MAX_IMAGE_PATTERNS); if(marker_info2) { wmarker_info = arGetMarkerInfo(dataPtr, marker_info2, &wmarker_num, _thresh); assert(wmarker_num <= MAX_IMAGE_PATTERNS); if(wmarker_info && wmarker_num>0) break; } } if(!autoThreshold.enable) break; else { _thresh = thresh = (rand() % 230) + 10; if(++numTries>autoThreshold.numRandomRetries) break; } } if(!limage || !marker_info2 || !wmarker_info) return -1; for( i = 0; i < prev_num; i++ ) { rlenmin = 10.0; cid = -1; for( j = 0; j < wmarker_num; j++ ) { rarea = (ARFloat)prev_info[i].marker.area / (ARFloat)wmarker_info[j].area; if( rarea < 0.7 || rarea > 1.43 ) continue; rlen = ( (wmarker_info[j].pos[0] - prev_info[i].marker.pos[0]) * (wmarker_info[j].pos[0] - prev_info[i].marker.pos[0]) + (wmarker_info[j].pos[1] - prev_info[i].marker.pos[1]) * (wmarker_info[j].pos[1] - prev_info[i].marker.pos[1]) ) / wmarker_info[j].area; if( rlen < 0.5 && rlen < rlenmin ) { rlenmin = rlen; cid = j; } } if( cid >= 0 && wmarker_info[cid].cf < prev_info[i].marker.cf ) { wmarker_info[cid].cf = prev_info[i].marker.cf; wmarker_info[cid].id = prev_info[i].marker.id; diffmin = 10000.0 * 10000.0; cdir = -1; for( j = 0; j < 4; j++ ) { diff = 0; for( k = 0; k < 4; k++ ) { diff += (prev_info[i].marker.vertex[k][0] - wmarker_info[cid].vertex[(j+k)%4][0]) * (prev_info[i].marker.vertex[k][0] - wmarker_info[cid].vertex[(j+k)%4][0]) + (prev_info[i].marker.vertex[k][1] - wmarker_info[cid].vertex[(j+k)%4][1]) * (prev_info[i].marker.vertex[k][1] - wmarker_info[cid].vertex[(j+k)%4][1]); } if( diff < diffmin ) { diffmin = diff; cdir = (prev_info[i].marker.dir - j + 4) % 4; } } wmarker_info[cid].dir = cdir; } } for( i = 0; i < wmarker_num; i++ ) { if( wmarker_info[i].cf < 0.5 ) wmarker_info[i].id = -1; } /*------------------------------------------------------------*/ for( i = j = 0; i < prev_num; i++ ) { prev_info[i].count++; if( prev_info[i].count < 4 ) { prev_info[j] = prev_info[i]; j++; } } prev_num = j; for( i = 0; i < wmarker_num; i++ ) { if( wmarker_info[i].id < 0 ) continue; for( j = 0; j < prev_num; j++ ) { if( prev_info[j].marker.id == wmarker_info[i].id ) break; } if(j<MAX_IMAGE_PATTERNS) { prev_info[j].marker = wmarker_info[i]; prev_info[j].count = 1; if( j == prev_num ) prev_num++; } } for( i = 0; i < prev_num; i++ ) { for( j = 0; j < wmarker_num; j++ ) { rarea = (ARFloat)prev_info[i].marker.area / (ARFloat)wmarker_info[j].area; if( rarea < 0.7 || rarea > 1.43 ) continue; rlen = ( (wmarker_info[j].pos[0] - prev_info[i].marker.pos[0]) * (wmarker_info[j].pos[0] - prev_info[i].marker.pos[0]) + (wmarker_info[j].pos[1] - prev_info[i].marker.pos[1]) * (wmarker_info[j].pos[1] - prev_info[i].marker.pos[1]) ) / wmarker_info[j].area; if( rlen < 0.5 ) break; } if(j==wmarker_num && wmarker_num<MAX_IMAGE_PATTERNS) { wmarker_info[wmarker_num] = prev_info[i].marker; wmarker_num++; assert(wmarker_num <= MAX_IMAGE_PATTERNS); } } *marker_num = wmarker_num; *marker_info = wmarker_info; assert(*marker_num <= MAX_IMAGE_PATTERNS); if(autoThreshold.enable) thresh = autoThreshold.calc(); return 0; }
// marker detection without using tracking history // AR_TEMPL_FUNC int AR_TEMPL_TRACKER::arDetectMarkerLite(uint8_t *dataPtr, int _thresh, ARMarkerInfo **marker_info, int *marker_num) { int16_t *limage = NULL; int label_num; int *area, *clip, *label_ref; ARFloat *pos; int i; trackedCorners.clear(); autoThreshold.reset(); checkImageBuffer(); *marker_num = 0; for(int numTries = 0;;) { limage = arLabeling(dataPtr, _thresh, &label_num, &area, &pos, &clip, &label_ref); if(limage) { marker_info2 = arDetectMarker2(limage, label_num, label_ref, area, pos, clip, AR_AREA_MAX, AR_AREA_MIN, 1.0, &wmarker_num); if(marker_info2) { wmarker_info = arGetMarkerInfo(dataPtr, marker_info2, &wmarker_num, _thresh); if(wmarker_info && wmarker_num>0) break; } } if(!autoThreshold.enable) break; else { _thresh = thresh = (rand() % 230) + 10; if(++numTries>autoThreshold.numRandomRetries) break; } } if(!limage || !marker_info2 || !wmarker_info) return -1; limage = arLabeling(dataPtr, _thresh, &label_num, &area, &pos, &clip, &label_ref); if( limage == 0 ) return -1; marker_info2 = arDetectMarker2(limage, label_num, label_ref, area, pos, clip, AR_AREA_MAX, AR_AREA_MIN, 1.0, &wmarker_num); if( marker_info2 == 0 ) return -1; wmarker_info = arGetMarkerInfo(dataPtr, marker_info2, &wmarker_num, _thresh); if( wmarker_info == 0 ) return -1; for( i = 0; i < wmarker_num; i++ ) if( wmarker_info[i].cf < 0.5 ) wmarker_info[i].id = -1; *marker_num = wmarker_num; *marker_info = wmarker_info; if(autoThreshold.enable) thresh = autoThreshold.calc(); return 0; }
int arDetectMarker( ARUint8 *dataPtr, int thresh, ARMarkerInfo **marker_info, int *marker_num ) { ARInt16 *limage; int label_num; int *area, *clip, *label_ref; double *pos; double rarea, rlen, rlenmin; double diff, diffmin; int cid, cdir; int i, j, k; *marker_num = 0; limage = arLabeling( dataPtr, thresh, &label_num, &area, &pos, &clip, &label_ref ); if( limage == 0 ) return -1; marker_info2 = arDetectMarker2( limage, label_num, label_ref, area, pos, clip, AR_AREA_MAX, AR_AREA_MIN, 1.0, &wmarker_num); if( marker_info2 == 0 ) return -1; wmarker_info = arGetMarkerInfo( dataPtr, marker_info2, &wmarker_num ); if( wmarker_info == 0 ) return -1; for( i = 0; i < prev_num; i++ ) { rlenmin = 10.0; cid = -1; for( j = 0; j < wmarker_num; j++ ) { rarea = (double)prev_info[i].marker.area / (double)wmarker_info[j].area; if( rarea < 0.7 || rarea > 1.43 ) continue; rlen = ( (wmarker_info[j].pos[0] - prev_info[i].marker.pos[0]) * (wmarker_info[j].pos[0] - prev_info[i].marker.pos[0]) + (wmarker_info[j].pos[1] - prev_info[i].marker.pos[1]) * (wmarker_info[j].pos[1] - prev_info[i].marker.pos[1]) ) / wmarker_info[j].area; if( rlen < 0.5 && rlen < rlenmin ) { rlenmin = rlen; cid = j; } } if( cid >= 0 && wmarker_info[cid].cf < prev_info[i].marker.cf ) { wmarker_info[cid].cf = prev_info[i].marker.cf; wmarker_info[cid].id = prev_info[i].marker.id; diffmin = 10000.0 * 10000.0; cdir = -1; for( j = 0; j < 4; j++ ) { diff = 0; for( k = 0; k < 4; k++ ) { diff += (prev_info[i].marker.vertex[k][0] - wmarker_info[cid].vertex[(j+k)%4][0]) * (prev_info[i].marker.vertex[k][0] - wmarker_info[cid].vertex[(j+k)%4][0]) + (prev_info[i].marker.vertex[k][1] - wmarker_info[cid].vertex[(j+k)%4][1]) * (prev_info[i].marker.vertex[k][1] - wmarker_info[cid].vertex[(j+k)%4][1]); } if( diff < diffmin ) { diffmin = diff; cdir = (prev_info[i].marker.dir - j + 4) % 4; } } wmarker_info[cid].dir = cdir; } } for( i = 0; i < wmarker_num; i++ ) { /* printf("cf = %g\n", wmarker_info[i].cf); */ if( wmarker_info[i].cf < 0.5 ) wmarker_info[i].id = -1; } /*------------------------------------------------------------*/ for( i = j = 0; i < prev_num; i++ ) { prev_info[i].count++; if( prev_info[i].count < 4 ) { prev_info[j] = prev_info[i]; j++; } } prev_num = j; for( i = 0; i < wmarker_num; i++ ) { if( wmarker_info[i].id < 0 ) continue; for( j = 0; j < prev_num; j++ ) { if( prev_info[j].marker.id == wmarker_info[i].id ) break; } prev_info[j].marker = wmarker_info[i]; prev_info[j].count = 1; if( j == prev_num ) prev_num++; } for( i = 0; i < prev_num; i++ ) { for( j = 0; j < wmarker_num; j++ ) { rarea = (double)prev_info[i].marker.area / (double)wmarker_info[j].area; if( rarea < 0.7 || rarea > 1.43 ) continue; rlen = ( (wmarker_info[j].pos[0] - prev_info[i].marker.pos[0]) * (wmarker_info[j].pos[0] - prev_info[i].marker.pos[0]) + (wmarker_info[j].pos[1] - prev_info[i].marker.pos[1]) * (wmarker_info[j].pos[1] - prev_info[i].marker.pos[1]) ) / wmarker_info[j].area; if( rlen < 0.5 ) break; } if( j == wmarker_num ) { wmarker_info[wmarker_num] = prev_info[i].marker; wmarker_num++; } } *marker_num = wmarker_num; *marker_info = wmarker_info; return 0; }
int arDetectMarker( ARUint8 *dataPtr, int thresh, ARMarkerInfo **marker_info, int *marker_num ) { ARInt16 *limage; int label_num; int *area, *clip, *label_ref; double *pos; double rarea, rlen, rlenmin; double diff, diffmin; int cid, cdir; int i, j, k; #ifdef DEBUG_LOGGING __android_log_write(ANDROID_LOG_INFO,"AR","entered arDetectMarker"); #endif *marker_num = 0; limage = arLabeling( dataPtr, thresh, &label_num, &area, &pos, &clip, &label_ref ); if( limage == 0 ) { #ifdef DEBUG_LOGGING __android_log_write(ANDROID_LOG_INFO,"AR","arLabeling not successful(returned 0)"); #endif return -1; } #ifdef DEBUG_LOGGING __android_log_print(ANDROID_LOG_INFO,"AR","detected %d labels",label_num); #endif marker_info2 = arDetectMarker2( limage, label_num, label_ref, area, pos, clip, AR_AREA_MAX, AR_AREA_MIN, 1.0, &wmarker_num); if( marker_info2 == 0 ) { #ifdef DEBUG_LOGGING __android_log_write(ANDROID_LOG_INFO,"AR","arDetectMarker not successful(returned 0)"); #endif return -1; } #ifdef DEBUG_LOGGING __android_log_print(ANDROID_LOG_INFO,"AR","got %d marker candidates",wmarker_num); #endif wmarker_info = arGetMarkerInfo( dataPtr, marker_info2, &wmarker_num ); if( wmarker_info == 0 ) { #ifdef DEBUG_LOGGING __android_log_write(ANDROID_LOG_INFO,"AR","arGetMarkerInfo not successful(returned 0)"); #endif return -1; } #ifdef DEBUG_LOGGING __android_log_print(ANDROID_LOG_INFO,"AR","got marker_info for %d markers",wmarker_num); #endif for( i = 0; i < prev_num; i++ ) { rlenmin = 10.0; cid = -1; for( j = 0; j < wmarker_num; j++ ) { rarea = (double)prev_info[i].marker.area / (double)wmarker_info[j].area; if( rarea < 0.7 || rarea > 1.43 ) { #ifdef DEBUG_LOGGING __android_log_print(ANDROID_LOG_INFO,"AR","relative area of marker %d too low or too high (%f)",i,rarea); #endif continue; } rlen = ( (wmarker_info[j].pos[0] - prev_info[i].marker.pos[0]) * (wmarker_info[j].pos[0] - prev_info[i].marker.pos[0]) + (wmarker_info[j].pos[1] - prev_info[i].marker.pos[1]) * (wmarker_info[j].pos[1] - prev_info[i].marker.pos[1]) ) / wmarker_info[j].area; if( rlen < AR_MIN_CF && rlen < rlenmin ) { rlenmin = rlen; cid = j; } } if( cid >= 0 && wmarker_info[cid].cf < prev_info[i].marker.cf ) { wmarker_info[cid].cf = prev_info[i].marker.cf; wmarker_info[cid].id = prev_info[i].marker.id; diffmin = 10000.0 * 10000.0; cdir = -1; for( j = 0; j < 4; j++ ) { diff = 0; for( k = 0; k < 4; k++ ) { diff += (prev_info[i].marker.vertex[k][0] - wmarker_info[cid].vertex[(j+k)%4][0]) * (prev_info[i].marker.vertex[k][0] - wmarker_info[cid].vertex[(j+k)%4][0]) + (prev_info[i].marker.vertex[k][1] - wmarker_info[cid].vertex[(j+k)%4][1]) * (prev_info[i].marker.vertex[k][1] - wmarker_info[cid].vertex[(j+k)%4][1]); } if( diff < diffmin ) { diffmin = diff; cdir = (prev_info[i].marker.dir - j + 4) % 4; } } wmarker_info[cid].dir = cdir; } } for( i = 0; i < wmarker_num; i++ ) { /* printf("cf = %g\n", wmarker_info[i].cf); */ #ifdef DEBUG_LOGGING __android_log_print(ANDROID_LOG_INFO,"AR","cf[i] = %g id[i]=%d",i,wmarker_info[i].cf,wmarker_info[i].id); #endif if( wmarker_info[i].cf < AR_MIN_CF ) { //#ifdef DEBUG_LOGGING __android_log_print(ANDROID_LOG_INFO,"AR","confidence value of marker %d too low(%f < %f)",i,wmarker_info[i].cf,AR_MIN_CF); //#endif wmarker_info[i].id = -1; } } /*------------------------------------------------------------*/ for( i = j = 0; i < prev_num; i++ ) { prev_info[i].count++; if( prev_info[i].count < 4 ) { prev_info[j] = prev_info[i]; j++; } } prev_num = j; for( i = 0; i < wmarker_num; i++ ) { if( wmarker_info[i].id < 0 ) continue; for( j = 0; j < prev_num; j++ ) { if( prev_info[j].marker.id == wmarker_info[i].id ) break; } prev_info[j].marker = wmarker_info[i]; prev_info[j].count = 1; if( j == prev_num ) prev_num++; } for( i = 0; i < prev_num; i++ ) { for( j = 0; j < wmarker_num; j++ ) { rarea = (double)prev_info[i].marker.area / (double)wmarker_info[j].area; if( rarea < 0.7 || rarea > 1.43 ) continue; rlen = ( (wmarker_info[j].pos[0] - prev_info[i].marker.pos[0]) * (wmarker_info[j].pos[0] - prev_info[i].marker.pos[0]) + (wmarker_info[j].pos[1] - prev_info[i].marker.pos[1]) * (wmarker_info[j].pos[1] - prev_info[i].marker.pos[1]) ) / wmarker_info[j].area; if( rlen < AR_MIN_CF ) break; } if( j == wmarker_num ) { wmarker_info[wmarker_num] = prev_info[i].marker; wmarker_num++; } } *marker_num = wmarker_num; *marker_info = wmarker_info; #ifdef DEBUG_LOGGING __android_log_print(ANDROID_LOG_INFO,"AR","left arDetectMarker, detected %d markers", wmarker_num); #endif return 0; }