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
NewLayerDialog::NewLayerDialog(const ImageComponents& original, QWidget* parent) : QDialog(parent) , _imp( new NewLayerDialogPrivate() ) { _imp->mainLayout = new QGridLayout(this); _imp->layerLabel = new Label(tr("Layer Name"), this); _imp->layerEdit = new LineEdit(this); _imp->numCompsLabel = new Label(tr("No. Channels"), this); _imp->numCompsBox = new SpinBox(this, SpinBox::eSpinBoxTypeInt); QObject::connect( _imp->numCompsBox, SIGNAL(valueChanged(double)), this, SLOT(onNumCompsChanged(double)) ); _imp->numCompsBox->setMinimum(1); _imp->numCompsBox->setMaximum(4); _imp->numCompsBox->setValue(4); _imp->rLabel = new Label(tr("1st Channel"), this); _imp->rEdit = new LineEdit(this); _imp->gLabel = new Label(tr("2nd Channel"), this); _imp->gEdit = new LineEdit(this); _imp->bLabel = new Label(tr("3rd Channel"), this); _imp->bEdit = new LineEdit(this); _imp->aLabel = new Label(tr("4th Channel"), this); _imp->aEdit = new LineEdit(this); _imp->setRgbaButton = new Button(this); _imp->setRgbaButton->setText( tr("Set RGBA") ); QObject::connect( _imp->setRgbaButton, SIGNAL(clicked(bool)), this, SLOT(onRGBAButtonClicked()) ); _imp->buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this); QObject::connect( _imp->buttons, SIGNAL(accepted()), this, SLOT(accept()) ); QObject::connect( _imp->buttons, SIGNAL(rejected()), this, SLOT(reject()) ); _imp->mainLayout->addWidget(_imp->layerLabel, 0, 0, 1, 1); _imp->mainLayout->addWidget(_imp->layerEdit, 0, 1, 1, 1); _imp->mainLayout->addWidget(_imp->numCompsLabel, 1, 0, 1, 1); _imp->mainLayout->addWidget(_imp->numCompsBox, 1, 1, 1, 1); _imp->mainLayout->addWidget(_imp->rLabel, 2, 0, 1, 1); _imp->mainLayout->addWidget(_imp->rEdit, 2, 1, 1, 1); _imp->mainLayout->addWidget(_imp->gLabel, 3, 0, 1, 1); _imp->mainLayout->addWidget(_imp->gEdit, 3, 1, 1, 1); _imp->mainLayout->addWidget(_imp->bLabel, 4, 0, 1, 1); _imp->mainLayout->addWidget(_imp->bEdit, 4, 1, 1, 1); _imp->mainLayout->addWidget(_imp->aLabel, 5, 0, 1, 1); _imp->mainLayout->addWidget(_imp->aEdit, 5, 1, 1, 1); _imp->mainLayout->addWidget(_imp->setRgbaButton, 6, 0, 1, 2); _imp->mainLayout->addWidget(_imp->buttons, 7, 0, 1, 2); if (original.getNumComponents() != 0) { _imp->layerEdit->setText( QString::fromUtf8( original.getLayerName().c_str() ) ); LineEdit* edits[4] = {_imp->rEdit, _imp->gEdit, _imp->bEdit, _imp->aEdit}; Label* labels[4] = {_imp->rLabel, _imp->gLabel, _imp->bLabel, _imp->aLabel}; const std::vector<std::string>& channels = original.getComponentsNames(); for (int i = 0; i < 4; ++i) { if ( i >= (int)channels.size() ) { edits[i]->setVisible(false); labels[i]->setVisible(false); } else { edits[i]->setText( QString::fromUtf8( channels[i].c_str() ) ); } } _imp->numCompsBox->setValue( (double)channels.size() ); } }