void TrackMarker::resetOffset() { KnobDoublePtr knob = getOffsetKnob(); for (int i = 0; i < knob->getDimension(); ++i) { knob->resetToDefaultValue(i); } }
void TrackMarker::setKeyFrameOnCenterAndPatternAtTime(int time) { KnobDoublePtr center = _imp->center.lock(); for (int i = 0; i < center->getDimension(); ++i) { double v = center->getValueAtTime(time, i); center->setValueAtTime(time, v, ViewSpec::all(), i); } KnobDoublePtr patternCorners[4] = {_imp->patternBtmLeft.lock(), _imp->patternTopLeft.lock(), _imp->patternTopRight.lock(), _imp->patternBtmRight.lock()}; for (int c = 0; c < 4; ++c) { KnobDoublePtr k = patternCorners[c]; for (int i = 0; i < k->getDimension(); ++i) { double v = k->getValueAtTime(time, i); k->setValueAtTime(time, v, ViewSpec::all(), i); } } }
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
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