Thumbnail::Thumbnail( IntrusivePtr<ThumbnailPixmapCache> const& thumbnail_cache, QSizeF const& max_size, ImageId const& image_id, Params const& params, ImageTransformation const& xform, QPolygonF const& phys_content_rect) : ThumbnailBase(thumbnail_cache, max_size, image_id, xform), m_params(params), m_virtContentRect(xform.transform().map(phys_content_rect).boundingRect()), m_virtOuterRect(xform.resultingPostCropArea().boundingRect()) { setExtendedClipArea(true); }
ImageView::ImageView( QImage const& image, QImage const& downscaled_image, ImageTransformation const& xform) : ImageViewBase( image, downscaled_image, ImagePresentation(xform.transform(), xform.resultingPreCropArea()) ), m_handlePixmap(":/icons/aqua-sphere.png"), m_dragHandler(*this), m_zoomHandler(*this), m_xform(xform) { setMouseTracking(true); interactionState().setDefaultStatusTip( tr("Use Ctrl+Wheel to rotate or Ctrl+Shift+Wheel for finer rotation.") ); QString const tip(tr("Drag this handle to rotate the image.")); double const hit_radius = std::max<double>(0.5 * m_handlePixmap.width(), 15.0); for (int i = 0; i < 2; ++i) { m_handles[i].setHitRadius(hit_radius); m_handles[i].setPositionCallback( boost::bind(&ImageView::handlePosition, this, i) ); m_handles[i].setMoveRequestCallback( boost::bind(&ImageView::handleMoveRequest, this, i, _1) ); m_handles[i].setDragFinishedCallback( boost::bind(&ImageView::dragFinished, this) ); m_handleInteractors[i].setProximityStatusTip(tip); m_handleInteractors[i].setObject(&m_handles[i]); makeLastFollower(m_handleInteractors[i]); } m_zoomHandler.setFocus(ZoomHandler::CENTER); rootInteractionHandler().makeLastFollower(*this); rootInteractionHandler().makeLastFollower(m_dragHandler); rootInteractionHandler().makeLastFollower(m_zoomHandler); }
OutputImageParams::OutputImageParams( QSize const& out_image_size, QRect const& content_rect, ImageTransformation const& xform, Dpi const& dpi, ColorParams const& color_params, DewarpingMode const& dewarping_mode, DistortionModel const& distortion_model, DepthPerception const& depth_perception, DespeckleLevel const despeckle_level) : m_size(out_image_size), m_contentRect(content_rect), m_partialXform(xform.transform()), m_dpi(dpi), m_colorParams(color_params), m_distortionModel(distortion_model), m_depthPerception(depth_perception), m_dewarpingMode(dewarping_mode), m_despeckleLevel(despeckle_level) { }
ImageView::ImageView( QImage const& image, QImage const& downscaled_image, ImageTransformation const& xform, PageLayout const& layout, IntrusivePtr<ProjectPages> const& pages, ImageId const& image_id, bool left_half_removed, bool right_half_removed) : ImageViewBase( image, downscaled_image, ImagePresentation(xform.transform(), xform.resultingPreCropArea()) ), m_ptrPages(pages), m_imageId(image_id), m_leftUnremoveButton(boost::bind(&ImageView::leftPageCenter, this)), m_rightUnremoveButton(boost::bind(&ImageView::rightPageCenter, this)), m_dragHandler(*this), m_zoomHandler(*this), m_handlePixmap(":/icons/aqua-sphere.png"), m_virtLayout(layout), m_leftPageRemoved(left_half_removed), m_rightPageRemoved(right_half_removed) { setMouseTracking(true); m_leftUnremoveButton.setClickCallback(boost::bind(&ImageView::unremoveLeftPage, this)); m_rightUnremoveButton.setClickCallback(boost::bind(&ImageView::unremoveRightPage, this)); if (m_leftPageRemoved) { makeLastFollower(m_leftUnremoveButton); } if (m_rightPageRemoved) { makeLastFollower(m_rightUnremoveButton); } setupCuttersInteraction(); rootInteractionHandler().makeLastFollower(*this); rootInteractionHandler().makeLastFollower(m_dragHandler); rootInteractionHandler().makeLastFollower(m_zoomHandler); }
bool performEstimation ( const FeatureAlgorithm& alg, const ImageTransformation& transformation, const cv::Mat& sourceImage, std::vector<FrameMatchingStatistics>& stat ) { Keypoints sourceKp; Descriptors sourceDesc; cv::Mat gray; if (sourceImage.channels() == 3) cv::cvtColor(sourceImage, gray, CV_BGR2GRAY); else if (sourceImage.channels() == 4) cv::cvtColor(sourceImage, gray, CV_BGRA2GRAY); else if(sourceImage.channels() == 1) gray = sourceImage; if (!alg.extractFeatures(gray, sourceKp, sourceDesc)) return false; std::vector<float> x = transformation.getX(); stat.resize(x.size()); const int count = x.size(); cv::Mat transformedImage; Keypoints resKpReal; Descriptors resDesc; Matches matches; // To convert ticks to milliseconds const double toMsMul = 1000. / cv::getTickFrequency(); #pragma omp parallel for private(transformedImage, resKpReal, resDesc, matches) for (int i = 0; i < count; i++) { float arg = x[i]; FrameMatchingStatistics& s = stat[i]; transformation.transform(arg, gray, transformedImage); int64 start = cv::getTickCount(); alg.extractFeatures(transformedImage, resKpReal, resDesc); // Initialize required fields s.isValid = resKpReal.size() > 0; s.argumentValue = arg; if (!s.isValid) continue; if (alg.knMatchSupported) { std::vector<Matches> knMatches; alg.matchFeatures(sourceDesc, resDesc, 2, knMatches); ratioTest(knMatches, 0.75, matches); // Compute percent of false matches that were rejected by ratio test s.ratioTestFalseLevel = (float)(knMatches.size() - matches.size()) / (float) knMatches.size(); } else { alg.matchFeatures(sourceDesc, resDesc, matches); } int64 end = cv::getTickCount(); Matches correctMatches; cv::Mat homography; bool homographyFound = ImageTransformation::findHomography(sourceKp, resKpReal, matches, correctMatches, homography); // Some simple stat: s.isValid = homographyFound; s.totalKeypoints = resKpReal.size(); s.consumedTimeMs = (end - start) * toMsMul; // Compute overall percent of matched keypoints s.percentOfMatches = (float) matches.size() / (float)(std::min(sourceKp.size(), resKpReal.size())); s.correctMatchesPercent = (float) correctMatches.size() / (float)matches.size(); // Compute matching statistics computeMatchesDistanceStatistics(correctMatches, s.meanDistance, s.stdDevDistance); } return true; }