Exemple #1
0
void
TrackMarker::resetTrack()
{
    Point curCenter;
    KnobDoublePtr knob = getCenterKnob();

    curCenter.x = knob->getValue(0);
    curCenter.y = knob->getValue(1);

    EffectInstancePtr effect = getContext()->getNode()->getEffectInstance();
    effect->beginChanges();

    const KnobsVec& knobs = getKnobs();
    for (KnobsVec::const_iterator it = knobs.begin(); it != knobs.end(); ++it) {
        if (*it != knob) {
            for (int i = 0; i < (*it)->getDimension(); ++i) {
                (*it)->resetToDefaultValue(i);
            }
        } else {
            for (int i = 0; i < (*it)->getDimension(); ++i) {
                (*it)->removeAnimation(ViewSpec::current(), i);
            }
            knob->setValue(curCenter.x, ViewSpec::current(), 0);
            knob->setValue(curCenter.y, ViewSpec::current(), 1);
        }
    }
    effect->endChanges();
    removeAllUserKeyframes();
}
Exemple #2
0
void
TrackMarker::resetTrack()
{
    Point curCenter;
    KnobDoublePtr centerKnob = getCenterKnob();

    curCenter.x = centerKnob->getValue();
    curCenter.y = centerKnob->getValue(DimIdx(1));

    const KnobsVec& knobs = getKnobs();
    for (KnobsVec::const_iterator it = knobs.begin(); it != knobs.end(); ++it) {
        if (*it != centerKnob) {
            (*it)->resetToDefaultValue(DimSpec::all(), ViewSetSpec::all());
        } else {
            (*it)->removeAnimation(ViewSetSpec::all(), DimSpec::all(), eValueChangedReasonUserEdited);

            std::vector<double> values(2);
            values[0] = curCenter.x;
            values[1] = curCenter.y;
            centerKnob->setValueAcrossDimensions(values);
        }
    }

    removeAnimation(ViewSetSpec::all(), DimSpec::all(), eValueChangedReasonUserEdited);
}
Exemple #3
0
void
TrackMarker::resetCenter()
{
    TrackerContextPtr context = getContext();

    assert(context);
    NodePtr input = context->getNode()->getInput(0);
    if (input) {
        SequenceTime time = input->getApp()->getTimeLine()->currentFrame();
        RenderScale scale;
        scale.x = scale.y = 1;
        RectD rod;
        bool isProjectFormat;
        StatusEnum stat = input->getEffectInstance()->getRegionOfDefinition_public(input->getHashValue(), time, scale, ViewIdx(0), &rod, &isProjectFormat);
        Point center;
        center.x = 0;
        center.y = 0;
        if (stat == eStatusOK) {
            center.x = (rod.x1 + rod.x2) / 2.;
            center.y = (rod.y1 + rod.y2) / 2.;
        }

        KnobDoublePtr centerKnob = getCenterKnob();
        centerKnob->setValue(center.x, ViewSpec::current(), 0);
        centerKnob->setValue(center.y, ViewSpec::current(), 1);
    }
}
Exemple #4
0
RectI
TrackMarker::getMarkerImageRoI(int time) const
{
    const unsigned int mipmapLevel = 0;
    Point center, offset;
    KnobDoublePtr centerKnob = getCenterKnob();
    KnobDoublePtr offsetKnob = getOffsetKnob();

    center.x = centerKnob->getValueAtTime(time, 0);
    center.y = centerKnob->getValueAtTime(time, 1);

    offset.x = offsetKnob->getValueAtTime(time, 0);
    offset.y = offsetKnob->getValueAtTime(time, 1);

    RectD roiCanonical;
    KnobDoublePtr swBl = getSearchWindowBottomLeftKnob();
    KnobDoublePtr swTr = getSearchWindowTopRightKnob();

    roiCanonical.x1 = swBl->getValueAtTime(time, 0) + center.x + offset.x;
    roiCanonical.y1 = swBl->getValueAtTime(time, 1) + center.y + offset.y;
    roiCanonical.x2 = swTr->getValueAtTime(time, 0) + center.x + offset.x;
    roiCanonical.y2 = swTr->getValueAtTime(time, 1) + center.y + offset.y;

    RectI roi;
    NodePtr node = getContext()->getNode();
    NodePtr input = node->getInput(0);
    if (!input) {
        return RectI();
    }
    roiCanonical.toPixelEnclosing(mipmapLevel, input ? input->getEffectInstance()->getAspectRatio(-1) : 1., &roi);

    return roi;
}
Exemple #5
0
void
TrackMarker::clearAnimationAfterTime(TimeValue time)
{
    std::set<double> userKeyframes;

    getMasterKeyFrameTimes(ViewIdx(0), &userKeyframes);

    KnobIPtr offsetKnob = getOffsetKnob();
    assert(offsetKnob);
    deleteKnobAnimation(userKeyframes, offsetKnob, eDeleteKnobAnimationAfterTime, time);

    KnobIPtr centerKnob = getCenterKnob();
    assert(centerKnob);
    deleteKnobAnimation(userKeyframes, centerKnob, eDeleteKnobAnimationAfterTime, time);

    KnobIPtr errorKnob = getErrorKnob();
    assert(errorKnob);
    deleteKnobAnimation(userKeyframes, errorKnob, eDeleteKnobAnimationAfterTime, time);
}
Exemple #6
0
void
TrackMarker::clearAnimationAfterTime(int time)
{
    std::set<int> userKeyframes;

    getUserKeyframes(&userKeyframes);

    KnobIPtr offsetKnob = getOffsetKnob();
    assert(offsetKnob);
    deleteKnobAnimation(userKeyframes, offsetKnob, eDeleteKnobAnimationAfterTime, time);

    KnobIPtr centerKnob = getCenterKnob();
    assert(centerKnob);
    deleteKnobAnimation(userKeyframes, centerKnob, eDeleteKnobAnimationAfterTime, time);

    KnobIPtr errorKnob = getErrorKnob();
    assert(errorKnob);
    deleteKnobAnimation(userKeyframes, errorKnob, eDeleteKnobAnimationAfterTime, time);
}
Exemple #7
0
RectD
TrackMarker::getMarkerImageRoI(TimeValue time) const
{
    Point center, offset;
    KnobDoublePtr centerKnob = getCenterKnob();
    KnobDoublePtr offsetKnob = getOffsetKnob();

    center.x = centerKnob->getValueAtTime(time, DimIdx(0));
    center.y = centerKnob->getValueAtTime(time, DimIdx(1));

    offset.x = offsetKnob->getValueAtTime(time, DimIdx(0));
    offset.y = offsetKnob->getValueAtTime(time, DimIdx(1));

    RectD roiCanonical;
    KnobDoublePtr swBl = getSearchWindowBottomLeftKnob();
    KnobDoublePtr swTr = getSearchWindowTopRightKnob();

    roiCanonical.x1 = swBl->getValueAtTime(time, DimIdx(0)) + center.x + offset.x;
    roiCanonical.y1 = swBl->getValueAtTime(time, DimIdx(1)) + center.y + offset.y;
    roiCanonical.x2 = swTr->getValueAtTime(time, DimIdx(0)) + center.x + offset.x;
    roiCanonical.y2 = swTr->getValueAtTime(time, DimIdx(1)) + center.y + offset.y;

    return roiCanonical;
}
Exemple #8
0
void
TrackMarker::resetCenter()
{
    KnobItemsTablePtr model = getModel();
    if (!model) {
        return;
    }
    RectD rod;
    NodePtr input = model->getNode()->getInput(0);
    if (!input) {
        Format f;
        getApp()->getProject()->getProjectDefaultFormat(&f);
        rod = f.toCanonicalFormat();
    } else {
        TimeValue time(input->getApp()->getTimeLine()->currentFrame());
        RenderScale scale(1.);
        RectD rod;
        {
            GetRegionOfDefinitionResultsPtr results;
            ActionRetCodeEnum stat = input->getEffectInstance()->getRegionOfDefinition_public(time, scale, ViewIdx(0), &results);
            if (!isFailureRetCode(stat)) {
                rod = results->getRoD();
            }
        }
        Point center;
        center.x = 0;
        center.y = 0;
        center.x = (rod.x1 + rod.x2) / 2.;
        center.y = (rod.y1 + rod.y2) / 2.;


        KnobDoublePtr centerKnob = getCenterKnob();
        centerKnob->setValue(center.x, ViewSetSpec::all(), DimIdx(0));
        centerKnob->setValue(center.y, ViewSetSpec::all(), DimIdx(1));
    }
}
Exemple #9
0
void
TrackMarkerPM::initializeKnobs()
{
    TrackMarker::initializeKnobs();
    NodePtr thisNode = getModel()->getNode();
    NodePtr node;
    {
        CreateNodeArgsPtr args(CreateNodeArgs::create( PLUGINID_OFX_TRACKERPM, NodeCollectionPtr() ));
        args->setProperty<bool>(kCreateNodeArgsPropVolatile, true);
        args->setProperty<bool>(kCreateNodeArgsPropNoNodeGUI, true);
        args->setProperty<std::string>(kCreateNodeArgsPropNodeInitialName, "TrackerPMNode");

        node = getApp()->createNode(args);
        if (!node) {
            throw std::runtime_error("Couldn't create plug-in " PLUGINID_OFX_TRACKERPM);
        }
        if (thisNode) {
            NodePtr inputNode = thisNode->getInput(0);
            if (inputNode) {
                node->connectInput(inputNode, 0);
            }
        }
        trackerNode = node;
    }

    KnobItemsTablePtr model = getModel();
    EffectInstancePtr effect;
    if (model) {
        effect = model->getNode()->getEffectInstance();
    }

    trackPrevButton = getNodeKnob<KnobButton>(node, kTrackerPMParamTrackingPrevious);
    trackNextButton = getNodeKnob<KnobButton>(node, kTrackerPMParamTrackingNext);
    KnobDoublePtr center = getNodeKnob<KnobDouble>(node, kTrackerPMParamTrackingCenterPoint);
    centerKnob = center;

    // Slave the center knob and unslave when tracking
    if ( !center->linkTo(getCenterKnob()) ) {
        throw std::runtime_error("Could not link center");
    }

    KnobDoublePtr offset = getNodeKnob<KnobDouble>(node, kTrackerPMParamTrackingOffset);

    // Slave the offset knob
    if ( !offset->linkTo( getOffsetKnob() ) ) {
        throw std::runtime_error("Could not link offset");
    }

    offsetKnob = offset;

    // Ref frame is set for each
    refFrameKnob = getNodeKnob<KnobInt>(node, kTrackerPMParamTrackingReferenceFrame);

    // Enable reference frame
    KnobBoolPtr enableRefFrameKnob = getNodeKnob<KnobBool>(node, kTrackerPMParamTrackingEnableReferenceFrame);
    enableRefFrameKnob->setValue(true);

    KnobChoicePtr scoreType = getNodeKnob<KnobChoice>(node, kTrackerPMParamScore);
    if (effect) {
#ifdef kTrackerParamPatternMatchingScoreType
        KnobIPtr modelKnob = effect->getKnobByName(kTrackerParamPatternMatchingScoreType);
        if (modelKnob) {
            if ( !scoreType->linkTo(modelKnob) ) {
                throw std::runtime_error("Could not link scoreType");
            }
        }
#endif
    }

    scoreTypeKnob = scoreType;

    KnobDoublePtr correlationScore = getNodeKnob<KnobDouble>(node, kTrackerPMParamTrackingCorrelationScore);
    correlationScoreKnob = correlationScore;

    KnobDoublePtr patternBtmLeft = getNodeKnob<KnobDouble>(node, kTrackerPMParamTrackingPatternBoxBtmLeft);
    patternBtmLeftKnob = patternBtmLeft;

    // Slave the search window and pattern of the node to the parameters of the marker
    (void)patternBtmLeft->linkTo(getPatternBtmLeftKnob());

    KnobDoublePtr patternTopRight = getNodeKnob<KnobDouble>(node, kTrackerPMParamTrackingPatternBoxTopRight);
    patternTopRightKnob = patternTopRight;
    (void)patternTopRight->linkTo(getPatternTopRightKnob());

    KnobDoublePtr searchWindowBtmLeft = getNodeKnob<KnobDouble>(node, kTrackerPMParamTrackingSearchBoxBtmLeft);
    searchWindowBtmLeftKnob = searchWindowBtmLeft;
    (void)searchWindowBtmLeft->linkTo(getSearchWindowBottomLeftKnob());

    KnobDoublePtr searchWindowTopRight = getNodeKnob<KnobDouble>(node, kTrackerPMParamTrackingSearchBoxTopRight);
    searchWindowTopRightKnob = searchWindowTopRight;
    (void)searchWindowTopRight->linkTo(getSearchWindowTopRightKnob());

} // TrackMarkerPM::initializeKnobs
Exemple #10
0
bool
TrackMarkerPM::trackMarker(bool forward,
                           int refFrame,
                           int frame)
{
    KnobButtonPtr button;

    if (forward) {
        button = trackNextButton.lock();
    } else {
        button = trackPrevButton.lock();
    }
    KnobIntPtr refFrameK = refFrameKnob.lock();
    refFrameK->setValue(refFrame);

    // Unslave the center knob since the trackerNode will update it, then update the marker center
    KnobDoublePtr center = centerKnob.lock();
    center->unlink(DimSpec::all(), ViewSetSpec::all(), true);

    trackerNode->getEffectInstance()->onKnobValueChanged_public(button, eValueChangedReasonUserEdited, TimeValue(frame), ViewIdx(0));

    KnobDoublePtr markerCenter = getCenterKnob();
    // The TrackerPM plug-in has set a keyframe at the refFrame and frame, copy them
    bool ret = true;
    double centerPoint[2];
    for (int i = 0; i < center->getNDimensions(); ++i) {
        {
            int index = center->getKeyFrameIndex(ViewIdx(0), DimIdx(i), TimeValue(frame));
            if (index != -1) {
                centerPoint[i] = center->getValueAtTime(TimeValue(frame), DimIdx(i));
                markerCenter->setValueAtTime(TimeValue(frame), centerPoint[i], ViewSetSpec::all(), DimIdx(i));
            } else {
                // No keyframe at this time: tracking failed
                ret = false;
                break;
            }
        }
        {
            int index = center->getKeyFrameIndex(ViewIdx(0), DimIdx(i), TimeValue(refFrame));
            if (index != -1) {
                double value = center->getValueAtTime(TimeValue(refFrame), DimIdx(i));
                markerCenter->setValueAtTime(TimeValue(refFrame), value, ViewSetSpec::all(), DimIdx(i));
            }
        }
    }

    // Convert the correlation score of the TrackerPM to the error
    if (ret) {
        KnobDoublePtr markerError = getErrorKnob();
        KnobDoublePtr correlation = correlationScoreKnob.lock();
        {
            int index = correlation->getKeyFrameIndex(ViewIdx(0), DimIdx(0), TimeValue(frame));
            if (index != -1) {
                // The error is estimated as a percentage of the correlation across the number of pixels in the pattern window
                KnobDoublePtr  pBtmLeft = patternBtmLeftKnob.lock();
                KnobDoublePtr  pTopRight = patternTopRightKnob.lock();
                Point btmLeft, topRight;

                btmLeft.x = pBtmLeft->getValueAtTime(TimeValue(frame), DimIdx(0));
                btmLeft.y = pBtmLeft->getValueAtTime(TimeValue(frame), DimIdx(1));

                topRight.x = pTopRight->getValueAtTime(TimeValue(frame), DimIdx(0));
                topRight.y = pTopRight->getValueAtTime(TimeValue(frame), DimIdx(1));


                double areaPixels = (topRight.x - btmLeft.x) * (topRight.y - btmLeft.y);
                NodePtr trackerInput = trackerNode->getInput(0);
                if (trackerInput) {
                    ImagePlaneDesc comps, paireComps;
                    trackerInput->getEffectInstance()->getMetadataComponents(-1, &comps, &paireComps);
                    areaPixels *= comps.getNumComponents();
                }

                double value = correlation->getValueAtTime(TimeValue(frame), DimIdx(0));

                // Convert to a percentage
                if (areaPixels > 0) {
                    value /= areaPixels;
                }

                markerError->setValueAtTime(TimeValue(frame), value, ViewSetSpec::all(), DimIdx(0));
            }
        }
    }

    if ( !center->linkTo(markerCenter) ) {
        throw std::runtime_error("Could not link center");
    }

    return ret;
} // TrackMarkerPM::trackMarker
Exemple #11
0
void
TrackMarkerPM::initializeKnobs()
{
    TrackMarker::initializeKnobs();
    NodePtr thisNode = getContext()->getNode();
    QObject::connect( getContext().get(), SIGNAL(onNodeInputChanged(int)), this, SLOT(onTrackerNodeInputChanged(int)) );
    NodePtr node;
    {
        CreateNodeArgs args( PLUGINID_OFX_TRACKERPM, NodeCollectionPtr() );
        args.setProperty<bool>(kCreateNodeArgsPropOutOfProject, true);
        args.setProperty<bool>(kCreateNodeArgsPropNoNodeGUI, true);
        args.setProperty<std::string>(kCreateNodeArgsPropNodeInitialName, "TrackerPMNode");

        node = getContext()->getNode()->getApp()->createNode(args);
        if (!node) {
            throw std::runtime_error("Couldn't create plug-in " PLUGINID_OFX_TRACKERPM);
        }
        if (thisNode) {
            NodePtr inputNode = thisNode->getInput(0);
            if (inputNode) {
                node->connectInput(inputNode, 0);
            }
        }
        trackerNode = node;
    }

    trackPrevButton = getNodeKnob<KnobButton>(node, kTrackerPMParamTrackingPrevious);
    trackNextButton = getNodeKnob<KnobButton>(node, kTrackerPMParamTrackingNext);
    KnobDoublePtr center = getNodeKnob<KnobDouble>(node, kTrackerPMParamTrackingCenterPoint);
    centerKnob = center;
    // Slave the center knob and unslave when tracking
    for (int i = 0; i < center->getDimension(); ++i) {
        center->slaveTo(i, getCenterKnob(), i);
    }

    KnobDoublePtr offset = getNodeKnob<KnobDouble>(node, kTrackerPMParamTrackingOffset);

    // Slave the offset knob
    for (int i = 0; i < offset->getDimension(); ++i) {
        offset->slaveTo(i, getOffsetKnob(), i);
    }
    offsetKnob = offset;

    // Ref frame is set for each
    refFrameKnob = getNodeKnob<KnobInt>(node, kTrackerPMParamTrackingReferenceFrame);

    // Enable reference frame
    KnobBoolPtr enableRefFrameKnob = getNodeKnob<KnobBool>(node, kTrackerPMParamTrackingEnableReferenceFrame);
    enableRefFrameKnob->setValue(true);

    KnobChoicePtr scoreType = getNodeKnob<KnobChoice>(node, kTrackerPMParamScore);
    scoreType->slaveTo(0, getContext()->getCorrelationScoreTypeKnob(), 0);
    scoreTypeKnob = scoreType;

    KnobDoublePtr correlationScore = getNodeKnob<KnobDouble>(node, kTrackerPMParamTrackingCorrelationScore);
    correlationScoreKnob = correlationScore;

    KnobDoublePtr patternBtmLeft = getNodeKnob<KnobDouble>(node, kTrackerPMParamTrackingPatternBoxBtmLeft);
    patternBtmLeftKnob = patternBtmLeft;

    // Slave the search window and pattern of the node to the parameters of the marker
    for (int i = 0; i < patternBtmLeft->getDimension(); ++i) {
        patternBtmLeft->slaveTo(i, getPatternBtmLeftKnob(), i);
    }
    KnobDoublePtr patternTopRight = getNodeKnob<KnobDouble>(node, kTrackerPMParamTrackingPatternBoxTopRight);
    patternTopRightKnob = patternTopRight;
    for (int i = 0; i < patternTopRight->getDimension(); ++i) {
        patternTopRight->slaveTo(i, getPatternTopRightKnob(), i);
    }

    KnobDoublePtr searchWindowBtmLeft = getNodeKnob<KnobDouble>(node, kTrackerPMParamTrackingSearchBoxBtmLeft);
    searchWindowBtmLeftKnob = searchWindowBtmLeft;
    for (int i = 0; i < searchWindowBtmLeft->getDimension(); ++i) {
        searchWindowBtmLeft->slaveTo(i, getSearchWindowBottomLeftKnob(), i);
    }

    KnobDoublePtr searchWindowTopRight = getNodeKnob<KnobDouble>(node, kTrackerPMParamTrackingSearchBoxTopRight);
    searchWindowTopRightKnob = searchWindowTopRight;
    for (int i = 0; i < searchWindowTopRight->getDimension(); ++i) {
        searchWindowTopRight->slaveTo(i, getSearchWindowTopRightKnob(), i);
    }
} // TrackMarkerPM::initializeKnobs
Exemple #12
0
bool
TrackMarkerPM::trackMarker(bool forward,
                           int refFrame,
                           int frame)
{
    KnobButtonPtr button;

    if (forward) {
        button = trackNextButton.lock();
    } else {
        button = trackPrevButton.lock();
    }
    KnobIntPtr refFrameK = refFrameKnob.lock();
    refFrameK->setValue(refFrame);

    // Unslave the center knob since the trackerNode will update it, then update the marker center
    KnobDoublePtr center = centerKnob.lock();
    for (int i = 0; i < center->getDimension(); ++i) {
        center->unSlave(i, true);
    }

    trackerNode->getEffectInstance()->onKnobValueChanged_public(button, eValueChangedReasonNatronInternalEdited, frame, ViewIdx(0),
                                                                true);

    KnobDoublePtr markerCenter = getCenterKnob();
    // The TrackerPM plug-in has set a keyframe at the refFrame and frame, copy them
    bool ret = true;
    double centerPoint[2];
    for (int i = 0; i < center->getDimension(); ++i) {
        {
            int index = center->getKeyFrameIndex(ViewSpec::current(), i, frame);
            if (index != -1) {
                centerPoint[i] = center->getValueAtTime(frame, i);
                markerCenter->setValueAtTime(frame, centerPoint[i], ViewSpec::current(), i);
            } else {
                // No keyframe at this time: tracking failed
                ret = false;
                break;
            }
        }
        {
            int index = center->getKeyFrameIndex(ViewSpec::current(), i, refFrame);
            if (index != -1) {
                double value = center->getValueAtTime(refFrame, i);
                markerCenter->setValueAtTime(refFrame, value, ViewSpec::current(), i);
            }
        }
    }

    // Convert the correlation score of the TrackerPM to the error
    if (ret) {
        KnobDoublePtr markerError = getErrorKnob();
        KnobDoublePtr correlation = correlationScoreKnob.lock();
        {
            int index = correlation->getKeyFrameIndex(ViewSpec::current(), 0, frame);
            if (index != -1) {
                // The error is estimated as a percentage of the correlation across the number of pixels in the pattern window
                KnobDoublePtr  pBtmLeft = patternBtmLeftKnob.lock();
                KnobDoublePtr  pTopRight = patternTopRightKnob.lock();
                Point btmLeft, topRight;

                btmLeft.x = pBtmLeft->getValueAtTime(frame, 0);
                btmLeft.y = pBtmLeft->getValueAtTime(frame, 1);

                topRight.x = pTopRight->getValueAtTime(frame, 0);
                topRight.y = pTopRight->getValueAtTime(frame, 1);


                double areaPixels = (topRight.x - btmLeft.x) * (topRight.y - btmLeft.y);
                NodePtr trackerInput = trackerNode->getInput(0);
                if (trackerInput) {
                    ImageComponents comps = trackerInput->getEffectInstance()->getComponents(-1);
                    areaPixels *= comps.getNumComponents();
                }

                double value = correlation->getValueAtTime(frame, 0);

                // Convert to a percentage
                value /= areaPixels;

                markerError->setValueAtTime(frame, value, ViewSpec::current(), 0);
            }
        }
    }

    for (int i = 0; i < center->getDimension(); ++i) {
        center->slaveTo(i, markerCenter, i);
    }

    return ret;
} // TrackMarkerPM::trackMarker