int arDetectMarkerLite( ARUint8 *dataPtr, int thresh,
                        ARMarkerInfo **marker_info, int *marker_num )
{
    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 < AR_CF_THRESHOLD ) wmarker_info[i].id = -1;
    }


    *marker_num  = wmarker_num;
    *marker_info = wmarker_info;

    return 0;
}
Exemplo n.º 2
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;
}
Exemplo n.º 4
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;
}
Exemplo n.º 5
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;
}
Exemplo n.º 6
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;
}
Exemplo n.º 7
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;
}