vendor: OpenCV 5.0.0 snapshot at 755e50675d97db9b7d449d8bd6b09888646f6c6e

This commit is contained in:
Gitea Mirror Bot
2026-08-22 00:11:13 +08:00
commit 12022378a3
3872 changed files with 2513409 additions and 0 deletions
+2
View File
@@ -0,0 +1,2 @@
set(the_description "Extended image processing module. It includes edge-aware filters and etc.")
ocv_define_module(ximgproc opencv_core opencv_imgproc opencv_geometry opencv_stereo opencv_imgcodecs opencv_video WRAP python java objc js)
+19
View File
@@ -0,0 +1,19 @@
Extended Image Processing
=========================
- Structured Forests
- Edge Boxes
- Domain Transform Filter
- Guided Filter
- Adaptive Manifold Filter
- Joint Bilateral Filter
- Superpixels
- Graph segmentation
- Selective search from segmentation
- Paillou Filter
- Fast Line Detector
- Deriche Filter
- Pei&Lin Normalization
- Ridge Detection Filter
- Binary morphology on run-length encoded images
- Ellipse Detector
Binary file not shown.

After

Width:  |  Height:  |  Size: 517 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 747 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 741 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 966 KiB

+418
View File
@@ -0,0 +1,418 @@
@inproceedings{ZitnickECCV14edgeBoxes,
author = {C. Lawrence Zitnick and Piotr Doll{\'a}r},
title = {Edge Boxes: Locating Object Proposals from Edges},
booktitle = {ECCV},
year = {2014},
}
@inproceedings{Dollar2013,
title={Structured forests for fast edge detection},
author={Doll{\'a}r, Piotr and Zitnick, C Lawrence},
booktitle={Computer Vision (ICCV), 2013 IEEE International Conference on},
pages={1841--1848},
year={2013},
organization={IEEE}
}
@incollection{VBRV14,
title={SEEDS: Superpixels extracted via energy-driven sampling},
author={Van den Bergh, Michael and Boix, Xavier and Roig, Gemma and de Capitani, Benjamin and Van Gool, Luc},
booktitle={Computer Vision--ECCV 2012},
pages={13--26},
year={2012},
publisher={Springer}
}
@inproceedings{Gastal11,
title={Domain transform for edge-aware image and video processing},
author={Gastal, Eduardo SL and Oliveira, Manuel M},
booktitle={ACM Transactions on Graphics (TOG)},
volume={30},
number={4},
pages={69},
year={2011},
organization={ACM}
}
@article{Gastal12,
title={Adaptive manifolds for real-time high-dimensional filtering},
author={Gastal, Eduardo SL and Oliveira, Manuel M},
journal={ACM Transactions on Graphics (TOG)},
volume={31},
number={4},
pages={33},
year={2012},
publisher={ACM}
}
@incollection{Kaiming10,
title={Guided image filtering},
author={He, Kaiming and Sun, Jian and Tang, Xiaoou},
booktitle={Computer Vision--ECCV 2010},
pages={1--14},
year={2010},
publisher={Springer}
}
@article{Kaiming15,
title={Fast guided filter},
author={He, Kaiming and Sun, Jian},
journal={arXiv preprint arXiv:1505.00996},
year={2015}
}
@inproceedings{Lee14,
title={Outdoor place recognition in urban environments using straight lines},
author={Lee, Jin Han and Lee, Sehyung and Zhang, Guoxuan and Lim, Jongwoo and Chung, Wan Kyun and Suh, Il Hong},
booktitle={2014 IEEE International Conference on Robotics and Automation (ICRA)},
pages={5550--5557},
year={2014},
organization={IEEE}
}
@inproceedings{Lim2013,
title={Sketch tokens: A learned mid-level representation for contour and object detection},
author={Lim, Joseph J and Zitnick, C Lawrence and Doll{\'a}r, Piotr},
booktitle={Computer Vision and Pattern Recognition (CVPR), 2013 IEEE Conference on},
pages={3158--3165},
year={2013},
organization={IEEE}
}
@incollection{PFF2004,
title={Efficient graph-based image segmentation},
author={Felzenszwalb, Pedro F and Huttenlocher, Daniel P},
journal={International Journal of Computer Vision},
volume={59},
number={2},
pages={167--181},
year={2004},
publisher={Springer}
}
@article{deriche1987,
title={Using Canny's criteria to derive a recursively implemented optimal edge detector},
author={Deriche Rachid},
journal={International journal of computer vision},
volume={1},
number={2},
pages={167--187},
year={1987},
publisher={Springer}
}
@article{uijlings2013selective,
title={Selective search for object recognition},
author={Uijlings, Jasper RR and van de Sande, Koen EA and Gevers, Theo and Smeulders, Arnold WM},
journal={International journal of computer vision},
volume={104},
number={2},
pages={154--171},
year={2013},
publisher={Springer}
}
@article{Min2014,
title={Fast global image smoothing based on weighted least squares},
author={Min, Dongbo and Choi, Sunghwan and Lu, Jiangbo and Ham, Bumsub and Sohn, Kwanghoon and Do, Minh N},
journal={Image Processing, IEEE Transactions on},
volume={23},
number={12},
pages={5638--5653},
year={2014},
publisher={IEEE}
}
@inproceedings{Farbman2008,
title={Edge-preserving decompositions for multi-scale tone and detail manipulation},
author={Farbman, Zeev and Fattal, Raanan and Lischinski, Dani and Szeliski, Richard},
booktitle={ACM Transactions on Graphics (TOG)},
volume={27},
number={3},
pages={67},
year={2008},
organization={ACM}
}
@inproceedings{xu2011image,
title={Image smoothing via L 0 gradient minimization},
author={Xu, Li and Lu, Cewu and Xu, Yi and Jia, Jiaya},
booktitle={ACM Transactions on Graphics (TOG)},
volume={30},
number={6},
pages={174},
year={2011},
organization={ACM}
}
@inproceedings{Revaud2015,
title={EpicFlow: Edge-Preserving Interpolation of Correspondences for Optical Flow},
author={Revaud, Jerome and Weinzaepfel, Philippe and Harchaoui, Zaid and Schmid, Cordelia},
booktitle={Computer Vision and Pattern Recognition (CVPR), IEEE Conference on},
pages={1164--1172},
year={2015}
}
@article{Achanta2012,
author = {Achanta, Radhakrishna and Shaji, Appu and Smith, Kevin and Lucchi, Aurelien and Fua, Pascal and Susstrunk, Sabine},
title = {SLIC Superpixels Compared to State-of-the-Art Superpixel Methods},
journal = {IEEE Trans. Pattern Anal. Mach. Intell.},
issue_date = {November 2012},
volume = {34},
number = {11},
month = {nov},
year = {2012},
issn = {0162-8828},
pages = {2274--2282},
numpages = {9},
url = {http://dx.doi.org/10.1109/TPAMI.2012.120},
doi = {10.1109/TPAMI.2012.120},
acmid = {2377556},
publisher = {IEEE Computer Society},
address = {Washington, DC, USA},
keywords = {Superpixels, segmentation, clustering, k-means}
}
@InProceedings{Liu_2017_IEEE,
author = {Liu, Yong-Jin and Yu, Cheng-Chi and Yu, Min-Jing and He, Ying},
title = {Intrinsic Manifold SLIC: A Simple and Efficient Method for Computing Content-Sensitive Superpixels},
journal = {IEEE Transactions on Pattern Analysis and Machine Intelligence},
issue_date = {March 2017},
volume = {PP},
month = {mar},
year = {2017},
issue = {99},
url = {https://doi.org/10.1109/TPAMI.2017.2686857},
doi = {10.1109/TPAMI.2017.2686857},
publisher = {IEEE Computer Society},
address = {Washington, DC, USA},
keywords = {Superpixels, segmentation, image manifold, centroidal Voronoi tessellation, geodesic distance}
}
@InProceedings{LiCVPR2015LSC,
author = {Li, Zhengqin and Chen, Jiansheng},
title = {Superpixel Segmentation Using Linear Spectral Clustering},
journal = {The IEEE Conference on Computer Vision and Pattern Recognition (CVPR)},
month = {June},
year = {2015}
}
@article{Cho2014,
title = {Bilateral Texture Filtering},
author = {Hojin Cho and Hyunjoon Lee and Henry Kang and Seungyong Lee},
journal = {ACM Transactions on Graphics},
year = {2014},
volume = {33},
number = {4},
month = {July},
pages = {128:1--128:8}
}
@incollection{zhang2014rolling,
title={Rolling guidance filter},
author={Zhang, Qi and Shen, Xiaoyong and Xu, Li and Jia, Jiaya},
booktitle={Computer Vision--ECCV 2014},
pages={815--830},
year={2014},
publisher={Springer}
}
@inproceedings{zhang2014100+,
title={100+ times faster weighted median filter (WMF)},
author={Zhang, Qi and Xu, Li and Jia, Jiaya},
booktitle={Computer Vision and Pattern Recognition (CVPR), 2014 IEEE Conference on},
pages={2830--2837},
year={2014},
organization={IEEE}
}
@article{paillou1997detecting,
title={Detecting step edges in noisy SAR images: a new linear operator},
author={Paillou, Philippe},
journal={IEEE transactions on geoscience and remote sensing},
volume={35},
number={1},
pages={191--196},
year={1997}
}
@book{Niblack1985,
title={An introduction to digital image processing},
author={Niblack, Wayne},
year={1985},
publisher={Strandberg Publishing Company}
}
@inproceedings{Sauvola1997,
title={Adaptive document binarization},
author={Sauvola, Jaakko and Seppanen, Tapio and Haapakoski, Sami and Pietikainen, Matti},
booktitle={Document Analysis and Recognition, 1997., Proceedings of the Fourth International Conference on},
volume={1},
pages={147--152},
year={1997},
organization={IEEE}
}
@article{Wolf2004,
title={Extraction and recognition of artificial text in multimedia documents},
author={Wolf, Christian and Jolion, J-M},
journal={Pattern Analysis \& Applications},
volume={6},
number={4},
pages={309--326},
year={2004},
publisher={Springer}
}
@inproceedings{Khurshid2009,
title={Comparison of Niblack inspired Binarization methods for ancient documents},
author={Khurshid, Khurram and Siddiqi, Imran and Faure, Claudie and Vincent, Nicole},
booktitle={IS\&T/SPIE Electronic Imaging},
pages={72470U--72470U},
year={2009},
organization={International Society for Optics and Photonics}
}
@article{BergerRaghunathan1998,
title={Coalescence in 2 dimensions: experiments on thin copolymer films and numerical simulations},
author={Berger, L and Raghunathan, V A and Launay, C and Ausserré, D and Gallot, Y},
journal={The European Physical Journal B - Condensed Matter and Complex Systems},
volume={2},
number={1},
pages={93-99},
year={1998},
publisher={Springer}
}
@article{PersoonFu1977,
title={Shape Discrimination Using Fourier Descriptors},
author={E Persoon and King-Sun Fu},
journal={IEEE Transactions on Pattern Analysis and Machine Intelligence},
volume={7},
number={3},
pages={170-179},
year={1977},
publisher={IEEE Computer Society}
}
@inproceedings{Breuel2008,
title = {Binary Morphology and Related Operations on Run-Length Representations.},
author = {Breuel, Thomas},
year = {2008},
month = {01},
pages = {159-166},
volume = {1},
booktitle = {VISAPP 2008 - 3rd International Conference on Computer Vision Theory and Applications, Proceedings}
}
@misc{Segleafvein,
title = {Best Way of Segmenting Veins in Leaves.},
author = {Niki Estner},
url = {https://dsp.stackexchange.com/a/1735}
}
@misc{M_RF,
title = {Ridge Filter Mathematica},
author = {Wolfram Mathematica},
url = {http://reference.wolfram.com/language/ref/RidgeFilter.html}
}
@inproceedings{BarronPoole2016,
author = {Jonathan T Barron and Ben Poole},
title={The Fast Bilateral Solver},
booktitle={European Conference on Computer Vision (ECCV)},
year={2016},
publisher={Springer International Publishing},
pages={617--632},
}
@inproceedings{BarronPoole2016,
author = {Jonathan T Barron and Ben Poole},
title={The Fast Bilateral Solver},
booktitle={European Conference on Computer Vision (ECCV)},
year={2016},
publisher={Springer International Publishing},
pages={617--632},
}
@inproceedings{Hu2017,
title={Robust interpolation of correspondences for large displacement optical flow},
author={Hu, Yinlin and Li, Yunsong and Song, Rui},
booktitle={IEEE Conference on Computer Vision and Pattern Recognition},
pages={481--489},
year={2017}
}
@article{topal2012edge,
title={Edge drawing: a combined real-time edge and segment detector},
author={Topal, Cihan and Akinlar, Cuneyt},
journal={Journal of Visual Communication and Image Representation},
volume={23},
number={6},
pages={862--872},
year={2012},
publisher={Elsevier}
}
@article{akinlar2011edlines,
title={EDLines: A real-time line segment detector with a false detection control},
author={Akinlar, Cuneyt and Topal, Cihan},
journal={Pattern Recognition Letters},
volume={32},
number={13},
pages={1633--1642},
year={2011},
publisher={Elsevier}
}
@article{akinlar2012edpf,
title={EDPF: a real-time parameter-free edge segment detector with a false detection control},
author={Akinlar, Cuneyt and Topal, Cihan},
journal={International Journal of Pattern Recognition and Artificial Intelligence},
volume={26},
number={01},
pages={1255002},
year={2012},
publisher={World Scientific}
}
@article{akinlar2013edcircles,
title={EDCircles: A real-time circle detector with a false detection control},
author={Akinlar, Cuneyt and Topal, Cihan},
journal={Pattern Recognition},
volume={46},
number={3},
pages={725--740},
year={2013},
publisher={Elsevier}
}
@article{akinlar201782,
title = {ColorED: Color edge and segment detection by Edge Drawing (ED)},
author = {Cuneyt Akinlar and Cihan Topal},
journal = {Journal of Visual Communication and Image Representation},
volume = {44},
pages = {82-94},
year = {2017},
publisher={Academic Press}
@article{loke2021accelerated,
title={Accelerated superpixel image segmentation with a parallelized DBSCAN algorithm},
author={Loke, Seng Cheong and MacDonald, Bruce A and Parsons, Matthew and W{\"u}nsche, Burkhard Claus},
journal={Journal of Real-Time Image Processing},
pages={1--16},
year={2021},
publisher={Springer}
}
@article{jia2017fast,
title={A fast ellipse detector using projective invariant pruning},
author={Jia, Qi and Fan, Xin and Luo, Zhongxuan and Song, Lianbo and Qiu, Tie},
journal={IEEE Transactions on Image Processing},
volume={26},
number={8},
pages={3665--3679},
year={2017},
publisher={IEEE}
}
@@ -0,0 +1,243 @@
/*
* By downloading, copying, installing or using the software you agree to this license.
* If you do not agree to this license, do not download, install,
* copy or use the software.
*
*
* License Agreement
* For Open Source Computer Vision Library
* (3 - clause BSD License)
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met :
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and / or other materials provided with the distribution.
*
* * Neither the names of the copyright holders nor the names of the contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* This software is provided by the copyright holders and contributors "as is" and
* any express or implied warranties, including, but not limited to, the implied
* warranties of merchantability and fitness for a particular purpose are disclaimed.
* In no event shall copyright holders or contributors be liable for any direct,
* indirect, incidental, special, exemplary, or consequential damages
* (including, but not limited to, procurement of substitute goods or services;
* loss of use, data, or profits; or business interruption) however caused
* and on any theory of liability, whether in contract, strict liability,
* or tort(including negligence or otherwise) arising in any way out of
* the use of this software, even if advised of the possibility of such damage.
*/
#ifndef __OPENCV_XIMGPROC_HPP__
#define __OPENCV_XIMGPROC_HPP__
#include "ximgproc/edge_filter.hpp"
#include "ximgproc/disparity_filter.hpp"
#include "ximgproc/sparse_match_interpolator.hpp"
#include "ximgproc/structured_edge_detection.hpp"
#include "ximgproc/edgeboxes.hpp"
#include "ximgproc/edge_drawing.hpp"
#include "ximgproc/scansegment.hpp"
#include "ximgproc/seeds.hpp"
#include "ximgproc/segmentation.hpp"
#include "ximgproc/fast_hough_transform.hpp"
#include "ximgproc/estimated_covariance.hpp"
#include "ximgproc/weighted_median_filter.hpp"
#include "ximgproc/slic.hpp"
#include "ximgproc/lsc.hpp"
#include "ximgproc/paillou_filter.hpp"
#include "ximgproc/fast_line_detector.hpp"
#include "ximgproc/deriche_filter.hpp"
#include "ximgproc/peilin.hpp"
#include "ximgproc/fourier_descriptors.hpp"
#include "ximgproc/ridgefilter.hpp"
#include "ximgproc/brightedges.hpp"
#include "ximgproc/run_length_morphology.hpp"
#include "ximgproc/edgepreserving_filter.hpp"
#include "ximgproc/color_match.hpp"
#include "ximgproc/radon_transform.hpp"
#include "ximgproc/find_ellipses.hpp"
/**
@defgroup ximgproc Extended Image Processing
@{
@defgroup ximgproc_edge Structured forests for fast edge detection
This module contains implementations of modern structured edge detection algorithms,
i.e. algorithms which somehow takes into account pixel affinities in natural images.
@defgroup ximgproc_edgeboxes EdgeBoxes
@defgroup ximgproc_filters Filters
@defgroup ximgproc_superpixel Superpixels
@defgroup ximgproc_segmentation Image segmentation
@defgroup ximgproc_fast_line_detector Fast line detector
@defgroup ximgproc_edge_drawing Edge Drawing
Edge Drawing (ED) algorithm for geometric feature extraction and validation.
The Edge Drawing (ED) algorithm is a proactive approach to the edge detection problem.
In contrast to many existing edge detection algorithms, which follow a subtractive
approach (i.e., applying gradient filters and eliminating pixels based on several rules,
such as non-maximal suppression and hysteresis in the Canny Edge Detector), the ED algorithm
operates via an additive strategy. It selects edge pixels one by one and connects them,
hence the name Edge Drawing.
ED offers several key advantages:
1. **Additive Strategy**: Instead of eliminating non-edge pixels after gradient filtering,
ED incrementally builds up edge segments by selecting and connecting pixels based on
their gradient response. This differs from traditional methods, which rely on
non-maximal suppression and hysteresis to filter out non-edge pixels.
2. **Edge Pixel Selection**: ED selects edge pixels by analyzing their local gradient
response, while also considering neighboring pixels. This results in smoother and
more continuous edge segments, as ED aims to maximize the overall gradient strength
along the edge segment.
3. **Edge Segment Formation**: Traditional methods, such as non-maximal suppression,
check whether a pixel has the maximum gradient response along its gradient direction,
eliminating it otherwise. However, this approach doesn't consider neighboring pixels,
often resulting in lower-quality edge segments. ED, on the other hand, joins a set of
edge pixels together by maximizing the total gradient response of the segment, leading
to high-quality, well-localized edges.
4. **Higher-Level Feature Extraction**: After forming edge segments, ED enables the
extraction of higher-level geometric features such as lines, circles, ellipses, and
other shapes, making it useful for tasks involving geometric feature extraction and validation.
The ED algorithm produces continuous, smooth, and localized edge segments, making it ideal
for applications requiring precise edge detection and geometric shape analysis.
@defgroup ximgproc_fourier Fourier descriptors
@defgroup ximgproc_run_length_morphology Binary morphology on run-length encoded image
These functions support morphological operations on binary images. In order to be fast and space efficient binary images are encoded with a run-length representation.
This representation groups continuous horizontal sequences of "on" pixels together in a "run". A run is charactarized by the column position of the first pixel in the run, the column
position of the last pixel in the run and the row position. This representation is very compact for binary images which contain large continuous areas of "on" and "off" pixels. A checkerboard
pattern would be a good example. The representation is not so suitable for binary images created from random noise images or other images where little correlation between neighboring pixels
exists.
The morphological operations supported here are very similar to the operations supported in the imgproc module. In general they are fast. However on several occasions they are slower than the functions
from imgproc. The structuring elements of cv::MORPH_RECT and cv::MORPH_CROSS have very good support from the imgproc module. Also small structuring elements are very fast in imgproc (presumably
due to opencl support). Therefore the functions from this module are recommended for larger structuring elements (cv::MORPH_ELLIPSE or self defined structuring elements). A sample application
(run_length_morphology_demo) is supplied which allows to compare the speed of some morphological operations for the functions using run-length encoding and the imgproc functions for a given image.
Run length encoded images are stored in standard opencv images. Images have a single column of cv::Point3i elements. The number of rows is the number of run + 1. The first row contains
the size of the original (not encoded) image. For the runs the following mapping is used (x: column begin, y: column end (last column), z: row).
The size of the original image is required for compatibility with the imgproc functions when the boundary handling requires that pixel outside the image boundary are
"on".
@}
*/
namespace cv
{
namespace ximgproc
{
//! @addtogroup ximgproc
//! @{
enum ThinningTypes{
THINNING_ZHANGSUEN = 0, // Thinning technique of Zhang-Suen
THINNING_GUOHALL = 1 // Thinning technique of Guo-Hall
};
/**
* @brief Specifies the binarization method to use in cv::ximgproc::niBlackThreshold
*/
enum LocalBinarizationMethods{
BINARIZATION_NIBLACK = 0, //!< Classic Niblack binarization. See @cite Niblack1985 .
BINARIZATION_SAUVOLA = 1, //!< Sauvola's technique. See @cite Sauvola1997 .
BINARIZATION_WOLF = 2, //!< Wolf's technique. See @cite Wolf2004 .
BINARIZATION_NICK = 3 //!< NICK technique. See @cite Khurshid2009 .
};
/** @brief Performs thresholding on input images using Niblack's technique or some of the
popular variations it inspired.
The function transforms a grayscale image to a binary image according to the formulae:
- **THRESH_BINARY**
\f[dst(x,y) = \fork{\texttt{maxValue}}{if \(src(x,y) > T(x,y)\)}{0}{otherwise}\f]
- **THRESH_BINARY_INV**
\f[dst(x,y) = \fork{0}{if \(src(x,y) > T(x,y)\)}{\texttt{maxValue}}{otherwise}\f]
where \f$T(x,y)\f$ is a threshold calculated individually for each pixel.
The threshold value \f$T(x, y)\f$ is determined based on the binarization method chosen. For
classic Niblack, it is the mean minus \f$ k \f$ times standard deviation of
\f$\texttt{blockSize} \times\texttt{blockSize}\f$ neighborhood of \f$(x, y)\f$.
The function can't process the image in-place.
@param _src Source 8-bit single-channel image.
@param _dst Destination image of the same size and the same type as src.
@param maxValue Non-zero value assigned to the pixels for which the condition is satisfied,
used with the THRESH_BINARY and THRESH_BINARY_INV thresholding types.
@param type Thresholding type, see cv::ThresholdTypes.
@param blockSize Size of a pixel neighborhood that is used to calculate a threshold value
for the pixel: 3, 5, 7, and so on.
@param k The user-adjustable parameter used by Niblack and inspired techniques. For Niblack, this is
normally a value between 0 and 1 that is multiplied with the standard deviation and subtracted from
the mean.
@param binarizationMethod Binarization method to use. By default, Niblack's technique is used.
Other techniques can be specified, see cv::ximgproc::LocalBinarizationMethods.
@param r The user-adjustable parameter used by Sauvola's technique. This is the dynamic range
of standard deviation.
@sa threshold, adaptiveThreshold
*/
CV_EXPORTS_W void niBlackThreshold( InputArray _src, OutputArray _dst,
double maxValue, int type,
int blockSize, double k, int binarizationMethod = BINARIZATION_NIBLACK,
double r = 128 );
/** @brief Applies a binary blob thinning operation, to achieve a skeletization of the input image.
The function transforms a binary blob image into a skeletized form using the technique of Zhang-Suen.
@param src Source 8-bit single-channel image, containing binary blobs, with blobs having 255 pixel values.
@param dst Destination image of the same size and the same type as src. The function can work in-place.
@param thinningType Value that defines which thinning algorithm should be used. See cv::ximgproc::ThinningTypes
*/
CV_EXPORTS_W void thinning( InputArray src, OutputArray dst, int thinningType = THINNING_ZHANGSUEN);
/** @brief Performs anisotropic diffusion on an image.
The function applies Perona-Malik anisotropic diffusion to an image. This is the solution to the partial differential equation:
\f[{\frac {\partial I}{\partial t}}={\mathrm {div}}\left(c(x,y,t)\nabla I\right)=\nabla c\cdot \nabla I+c(x,y,t)\Delta I\f]
Suggested functions for c(x,y,t) are:
\f[c\left(\|\nabla I\|\right)=e^{{-\left(\|\nabla I\|/K\right)^{2}}}\f]
or
\f[ c\left(\|\nabla I\|\right)={\frac {1}{1+\left({\frac {\|\nabla I\|}{K}}\right)^{2}}} \f]
@param src Source image with 3 channels.
@param dst Destination image of the same size and the same number of channels as src .
@param alpha The amount of time to step forward by on each iteration (normally, it's between 0 and 1).
@param K sensitivity to the edges
@param niters The number of iterations
*/
CV_EXPORTS_W void anisotropicDiffusion(InputArray src, OutputArray dst, float alpha, float K, int niters );
//! @}
}
}
#endif // __OPENCV_XIMGPROC_HPP__
@@ -0,0 +1,50 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2017, IBM Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// @Authors
// Marc Fiammante marc.fiammante@fr.ibm.com
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of OpenCV Foundation or contributors may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the OpenCV Foundation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "opencv2/core.hpp"
namespace cv
{
namespace ximgproc {
CV_EXPORTS_W void BrightEdges(Mat &_original, Mat &_edgeview, int contrast = 1, int shortrange = 3, int longrange = 9);
}
}
@@ -0,0 +1,68 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifndef __OPENCV_COLOR_MATCH_HPP__
#define __OPENCV_COLOR_MATCH_HPP__
#include <opencv2/core.hpp>
namespace cv {
namespace ximgproc {
//! @addtogroup ximgproc_filters
//! @{
/**
* @brief creates a quaternion image.
*
* @param img Source 8-bit, 32-bit or 64-bit image, with 3-channel image.
* @param qimg result CV_64FC4 a quaternion image( 4 chanels zero channel and B,G,R).
*/
CV_EXPORTS_W void createQuaternionImage(InputArray img, OutputArray qimg);
/**
* @brief calculates conjugate of a quaternion image.
*
* @param qimg quaternion image.
* @param qcimg conjugate of qimg
*/
CV_EXPORTS_W void qconj(InputArray qimg, OutputArray qcimg);
/**
* @brief divides each element by its modulus.
*
* @param qimg quaternion image.
* @param qnimg conjugate of qimg
*/
CV_EXPORTS_W void qunitary(InputArray qimg, OutputArray qnimg);
/**
* @brief Calculates the per-element quaternion product of two arrays
*
* @param src1 quaternion image.
* @param src2 quaternion image.
* @param dst product dst(I)=src1(I) . src2(I)
*/
CV_EXPORTS_W void qmultiply(InputArray src1, InputArray src2, OutputArray dst);
/**
* @brief Performs a forward or inverse Discrete quaternion Fourier transform of a 2D quaternion array.
*
* @param img quaternion image.
* @param qimg quaternion image in dual space.
* @param flags quaternion image in dual space. only DFT_INVERSE flags is supported
* @param sideLeft true the hypercomplex exponential is to be multiplied on the left (false on the right ).
*/
CV_EXPORTS_W void qdft(InputArray img, OutputArray qimg, int flags, bool sideLeft);
/**
* @brief Compares a color template against overlapped color image regions.
*
* @param img Image where the search is running. It must be 3 channels image
* @param templ Searched template. It must be not greater than the source image and have 3 channels
* @param result Map of comparison results. It must be single-channel 64-bit floating-point
*/
CV_EXPORTS_W void colorMatchTemplate(InputArray img, InputArray templ, OutputArray result);
//! @}
}
}
#endif
@@ -0,0 +1,79 @@
/*
* By downloading, copying, installing or using the software you agree to this license.
* If you do not agree to this license, do not download, install,
* copy or use the software.
*
*
* License Agreement
* For Open Source Computer Vision Library
* (3 - clause BSD License)
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met :
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and / or other materials provided with the distribution.
*
* * Neither the names of the copyright holders nor the names of the contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* This software is provided by the copyright holders and contributors "as is" and
* any express or implied warranties, including, but not limited to, the implied
* warranties of merchantability and fitness for a particular purpose are disclaimed.
* In no event shall copyright holders or contributors be liable for any direct,
* indirect, incidental, special, exemplary, or consequential damages
* (including, but not limited to, procurement of substitute goods or services;
* loss of use, data, or profits; or business interruption) however caused
* and on any theory of liability, whether in contract, strict liability,
* or tort(including negligence or otherwise) arising in any way out of
* the use of this software, even if advised of the possibility of such damage.
*/
#ifndef __OPENCV_DERICHEFILTER_HPP__
#define __OPENCV_DERICHEFILTER_HPP__
#ifdef __cplusplus
#include <opencv2/core.hpp>
namespace cv {
namespace ximgproc {
//! @addtogroup ximgproc_filters
//! @{
/**
* @brief Applies Y Deriche filter to an image.
*
* For more details about this implementation, please see http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.476.5736&rep=rep1&type=pdf
*
* @param op Source 8-bit or 16bit image, 1-channel or 3-channel image.
* @param dst result CV_32FC image with same number of channel than _op.
* @param alpha double see paper
* @param omega double see paper
*
*/
CV_EXPORTS_W void GradientDericheY(InputArray op, OutputArray dst, double alpha,double omega);
/**
* @brief Applies X Deriche filter to an image.
*
* For more details about this implementation, please see http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.476.5736&rep=rep1&type=pdf
*
* @param op Source 8-bit or 16bit image, 1-channel or 3-channel image.
* @param dst result CV_32FC image with same number of channel than _op.
* @param alpha double see paper
* @param omega double see paper
*
*/
CV_EXPORTS_W void GradientDericheX(InputArray op, OutputArray dst, double alpha,double omega);
//! @}
}
}
#endif
#endif
@@ -0,0 +1,214 @@
/*
* By downloading, copying, installing or using the software you agree to this license.
* If you do not agree to this license, do not download, install,
* copy or use the software.
*
*
* License Agreement
* For Open Source Computer Vision Library
* (3 - clause BSD License)
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met :
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and / or other materials provided with the distribution.
*
* * Neither the names of the copyright holders nor the names of the contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* This software is provided by the copyright holders and contributors "as is" and
* any express or implied warranties, including, but not limited to, the implied
* warranties of merchantability and fitness for a particular purpose are disclaimed.
* In no event shall copyright holders or contributors be liable for any direct,
* indirect, incidental, special, exemplary, or consequential damages
* (including, but not limited to, procurement of substitute goods or services;
* loss of use, data, or profits; or business interruption) however caused
* and on any theory of liability, whether in contract, strict liability,
* or tort(including negligence or otherwise) arising in any way out of
* the use of this software, even if advised of the possibility of such damage.
*/
#ifndef __OPENCV_DISPARITYFILTER_HPP__
#define __OPENCV_DISPARITYFILTER_HPP__
#ifdef __cplusplus
#include <opencv2/core.hpp>
#include <opencv2/stereo.hpp>
namespace cv {
namespace ximgproc {
//! @addtogroup ximgproc_filters
//! @{
/** @brief Main interface for all disparity map filters.
*/
class CV_EXPORTS_W DisparityFilter : public Algorithm
{
public:
/** @brief Apply filtering to the disparity map.
@param disparity_map_left disparity map of the left view, 1 channel, CV_16S type. Implicitly assumes that disparity
values are scaled by 16 (one-pixel disparity corresponds to the value of 16 in the disparity map). Disparity map
can have any resolution, it will be automatically resized to fit left_view resolution.
@param left_view left view of the original stereo-pair to guide the filtering process, 8-bit single-channel
or three-channel image.
@param filtered_disparity_map output disparity map, single-channel CV_16S type,
with disparity values scaled by 16.
@param disparity_map_right optional argument, some implementations might also use the disparity map
of the right view to compute confidence maps. If provided, it must be a single-channel CV_16S matrix.
Disparity values are expected to be scaled by 16 (one-pixel disparity corresponds to the value of 16).
@param ROI region of the disparity map to filter. Optional, usually it should be set automatically.
@param right_view optional argument, some implementations might also use the right view of the original
stereo-pair.
*/
CV_WRAP virtual void filter(InputArray disparity_map_left, InputArray left_view, OutputArray filtered_disparity_map, InputArray disparity_map_right = Mat(), Rect ROI = Rect(), InputArray right_view = Mat()) = 0;
};
/** @brief Disparity map filter based on Weighted Least Squares filter (in form of Fast Global Smoother that
is a lot faster than traditional Weighted Least Squares filter implementations) and optional use of
left-right-consistency-based confidence to refine the results in half-occlusions and uniform areas.
*/
class CV_EXPORTS_W DisparityWLSFilter : public DisparityFilter
{
public:
/** filter parameters */
/** @brief Lambda is a parameter defining the amount of regularization during filtering. Larger values force
filtered disparity map edges to adhere more to source image edges. Typical value is 8000.
*/
CV_WRAP virtual double getLambda() = 0;
/** @see getLambda */
CV_WRAP virtual void setLambda(double _lambda) = 0;
/** @brief SigmaColor is a parameter defining how sensitive the filtering process is to source image edges.
Large values can lead to disparity leakage through low-contrast edges. Small values can make the filter too
sensitive to noise and textures in the source image. Typical values range from 0.8 to 2.0.
*/
CV_WRAP virtual double getSigmaColor() = 0;
/** @see getSigmaColor */
CV_WRAP virtual void setSigmaColor(double _sigma_color) = 0;
/** confidence-related parameters */
/** @brief LRCthresh is a threshold of disparity difference used in left-right-consistency check during
confidence map computation. The default value of 24 (1.5 pixels) is virtually always good enough.
*/
CV_WRAP virtual int getLRCthresh() = 0;
/** @see getLRCthresh */
CV_WRAP virtual void setLRCthresh(int _LRC_thresh) = 0;
/** @brief DepthDiscontinuityRadius is a parameter used in confidence computation. It defines the size of
low-confidence regions around depth discontinuities.
*/
CV_WRAP virtual int getDepthDiscontinuityRadius() = 0;
/** @see getDepthDiscontinuityRadius */
CV_WRAP virtual void setDepthDiscontinuityRadius(int _disc_radius) = 0;
/** @brief Get the confidence map that was used in the last filter call. It is a CV_32F one-channel image
with values ranging from 0.0 (totally untrusted regions of the raw disparity map) to 255.0 (regions containing
correct disparity values with a high degree of confidence).
*/
CV_WRAP virtual Mat getConfidenceMap() = 0;
/** @brief Get the ROI used in the last filter call
*/
CV_WRAP virtual Rect getROI() = 0;
};
/** @brief Convenience factory method that creates an instance of DisparityWLSFilter and sets up all the relevant
filter parameters automatically based on the matcher instance. Currently supports only StereoBM and StereoSGBM.
@param matcher_left stereo matcher instance that will be used with the filter
*/
CV_EXPORTS_W
Ptr<DisparityWLSFilter> createDisparityWLSFilter(Ptr<StereoMatcher> matcher_left);
/** @brief Convenience method to set up the matcher for computing the right-view disparity map
that is required in case of filtering with confidence.
@param matcher_left main stereo matcher instance that will be used with the filter
*/
CV_EXPORTS_W
Ptr<StereoMatcher> createRightMatcher(Ptr<StereoMatcher> matcher_left);
/** @brief More generic factory method, create instance of DisparityWLSFilter and execute basic
initialization routines. When using this method you will need to set-up the ROI, matchers and
other parameters by yourself.
@param use_confidence filtering with confidence requires two disparity maps (for the left and right views) and is
approximately two times slower. However, quality is typically significantly better.
*/
CV_EXPORTS_W
Ptr<DisparityWLSFilter> createDisparityWLSFilterGeneric(bool use_confidence);
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
/** @brief Function for reading ground truth disparity maps. Supports basic Middlebury
and MPI-Sintel formats. Note that the resulting disparity map is scaled by 16.
@param src_path path to the image, containing ground-truth disparity map
@param dst output disparity map, CV_16S depth
@result returns zero if successfully read the ground truth
*/
CV_EXPORTS_W
int readGT(String src_path,OutputArray dst);
/** @brief Function for computing mean square error for disparity maps
@param GT ground truth disparity map
@param src disparity map to evaluate
@param ROI region of interest
@result returns mean square error between GT and src
*/
CV_EXPORTS_W
double computeMSE(InputArray GT, InputArray src, Rect ROI);
/** @brief Function for computing the percent of "bad" pixels in the disparity map
(pixels where error is higher than a specified threshold)
@param GT ground truth disparity map
@param src disparity map to evaluate
@param ROI region of interest
@param thresh threshold used to determine "bad" pixels
@result returns mean square error between GT and src
*/
CV_EXPORTS_W
double computeBadPixelPercent(InputArray GT, InputArray src, Rect ROI, int thresh=24/*1.5 pixels*/);
/** @brief Function for creating a disparity map visualization (clamped CV_8U image)
@param src input disparity map (CV_16S depth)
@param dst output visualization
@param scale disparity map will be multiplied by this value for visualization
*/
CV_EXPORTS_W
void getDisparityVis(InputArray src,OutputArray dst,double scale=1.0);
//! @}
}
}
#endif
#endif
@@ -0,0 +1,132 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifndef __OPENCV_EDGE_DRAWING_HPP__
#define __OPENCV_EDGE_DRAWING_HPP__
#include <opencv2/core.hpp>
namespace cv
{
namespace ximgproc
{
//! @addtogroup ximgproc_edge_drawing
//! @{
/** @brief Class implementing the ED (EdgeDrawing) @cite topal2012edge, EDLines @cite akinlar2011edlines, EDPF @cite akinlar2012edpf, EDCircles @cite akinlar2013edcircles and ColorED @cite akinlar201782 algorithms.
*/
class CV_EXPORTS_W EdgeDrawing : public Algorithm
{
public:
enum GradientOperator
{
PREWITT = 0,
SOBEL = 1,
SCHARR = 2,
LSD = 3
};
struct CV_EXPORTS_W_SIMPLE Params
{
CV_WRAP Params();
//! Parameter Free mode will be activated when this value is set as true. Default value is false.
CV_PROP_RW bool PFmode;
/** @brief indicates the operator used for gradient calculation.
one of the flags cv::ximgproc::EdgeDrawing::GradientOperator. Default value is PREWITT
*/
CV_PROP_RW int EdgeDetectionOperator;
//! threshold value of gradiential difference between pixels. Used to create gradient image. Default value is 20
CV_PROP_RW int GradientThresholdValue;
//! threshold value used to select anchor points. Default value is 0
CV_PROP_RW int AnchorThresholdValue;
//! Default value is 1
CV_PROP_RW int ScanInterval;
/** @brief minimun connected pixels length processed to create an edge segment.
in gradient image, minimum connected pixels length processed to create an edge segment. pixels having upper value than GradientThresholdValue
will be processed. Default value is 10
*/
CV_PROP_RW int MinPathLength;
//! sigma value for internal GaussianBlur() function. Default value is 1.0
CV_PROP_RW float Sigma;
CV_PROP_RW bool SumFlag;
//! Default value is true. indicates if NFA (Number of False Alarms) algorithm will be used for line and ellipse validation.
CV_PROP_RW bool NFAValidation;
//! minimun line length to detect.
CV_PROP_RW int MinLineLength;
//! Default value is 6.0
CV_PROP_RW double MaxDistanceBetweenTwoLines;
//! Default value is 1.0
CV_PROP_RW double LineFitErrorThreshold;
//! Default value is 1.3
CV_PROP_RW double MaxErrorThreshold;
CV_WRAP void read(const FileNode& fn);
CV_WRAP void write(FileStorage& fs) const;
};
/** @brief Detects edges in a grayscale or color image and prepares them to detect lines and ellipses.
@param src 8-bit, single-channel (CV_8UC1) or color (CV_8UC3, CV_8UC4) input image.
*/
CV_WRAP virtual void detectEdges(InputArray src) = 0;
/** @brief returns Edge Image prepared by detectEdges() function.
@param dst returns 8-bit, single-channel output image.
*/
CV_WRAP virtual void getEdgeImage(OutputArray dst) = 0;
/** @brief returns Gradient Image prepared by detectEdges() function.
@param dst returns 16-bit, single-channel output image.
*/
CV_WRAP virtual void getGradientImage(OutputArray dst) = 0;
/** @brief Returns std::vector<std::vector<Point>> of detected edge segments, see detectEdges()
*/
CV_WRAP virtual std::vector<std::vector<Point> > getSegments() = 0;
/** @brief Returns for each line found in detectLines() its edge segment index in getSegments()
*/
CV_WRAP virtual std::vector<int> getSegmentIndicesOfLines() const = 0;
/** @brief Detects lines.
@param lines output Vec<4f> contains the start point and the end point of detected lines.
@note you should call detectEdges() before calling this function.
*/
CV_WRAP virtual void detectLines(OutputArray lines) = 0;
/** @brief Detects circles and ellipses.
@param ellipses output Vec<6d> contains center point and perimeter for circles, center point, axes and angle for ellipses.
@note you should call detectEdges() before calling this function.
*/
CV_WRAP virtual void detectEllipses(OutputArray ellipses) = 0;
CV_WRAP Params params;
/** @brief sets parameters.
this function is meant to be used for parameter setting in other languages than c++ like python.
@param parameters Parameters of the algorithm
*/
CV_WRAP void setParams(const EdgeDrawing::Params& parameters);
virtual ~EdgeDrawing() { }
};
/** @brief Creates a smart pointer to a EdgeDrawing object and initializes it
*/
CV_EXPORTS_W Ptr<EdgeDrawing> createEdgeDrawing();
//! @}
}
}
#endif /* __OPENCV_EDGE_DRAWING_HPP__ */
@@ -0,0 +1,534 @@
/*
* By downloading, copying, installing or using the software you agree to this license.
* If you do not agree to this license, do not download, install,
* copy or use the software.
*
*
* License Agreement
* For Open Source Computer Vision Library
* (3 - clause BSD License)
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met :
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and / or other materials provided with the distribution.
*
* * Neither the names of the copyright holders nor the names of the contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* This software is provided by the copyright holders and contributors "as is" and
* any express or implied warranties, including, but not limited to, the implied
* warranties of merchantability and fitness for a particular purpose are disclaimed.
* In no event shall copyright holders or contributors be liable for any direct,
* indirect, incidental, special, exemplary, or consequential damages
* (including, but not limited to, procurement of substitute goods or services;
* loss of use, data, or profits; or business interruption) however caused
* and on any theory of liability, whether in contract, strict liability,
* or tort(including negligence or otherwise) arising in any way out of
* the use of this software, even if advised of the possibility of such damage.
*/
#ifndef __OPENCV_EDGEFILTER_HPP__
#define __OPENCV_EDGEFILTER_HPP__
#ifdef __cplusplus
#include <opencv2/core.hpp>
namespace cv
{
namespace ximgproc
{
//! @addtogroup ximgproc_filters
//! @{
enum EdgeAwareFiltersList
{
DTF_NC,
DTF_IC,
DTF_RF,
GUIDED_FILTER,
AM_FILTER
};
/** @brief Interface for realizations of Domain Transform filter.
For more details about this filter see @cite Gastal11 .
*/
class CV_EXPORTS_W DTFilter : public Algorithm
{
public:
/** @brief Produce domain transform filtering operation on source image.
@param src filtering image with unsigned 8-bit or floating-point 32-bit depth and up to 4 channels.
@param dst destination image.
@param dDepth optional depth of the output image. dDepth can be set to -1, which will be equivalent
to src.depth().
*/
CV_WRAP virtual void filter(InputArray src, OutputArray dst, int dDepth = -1) = 0;
};
/** @brief Factory method, create instance of DTFilter and produce initialization routines.
@param guide guided image (used to build transformed distance, which describes edge structure of
guided image).
@param sigmaSpatial \f${\sigma}_H\f$ parameter in the original article, it's similar to the sigma in the
coordinate space into bilateralFilter.
@param sigmaColor \f${\sigma}_r\f$ parameter in the original article, it's similar to the sigma in the
color space into bilateralFilter.
@param mode one form three modes DTF_NC, DTF_RF and DTF_IC which corresponds to three modes for
filtering 2D signals in the article.
@param numIters optional number of iterations used for filtering, 3 is quite enough.
For more details about Domain Transform filter parameters, see the original article @cite Gastal11 and
[Domain Transform filter homepage](http://www.inf.ufrgs.br/~eslgastal/DomainTransform/).
*/
CV_EXPORTS_W
Ptr<DTFilter> createDTFilter(InputArray guide, double sigmaSpatial, double sigmaColor, int mode = DTF_NC, int numIters = 3);
/** @brief Simple one-line Domain Transform filter call. If you have multiple images to filter with the same
guided image then use DTFilter interface to avoid extra computations on initialization stage.
@param guide guided image (also called as joint image) with unsigned 8-bit or floating-point 32-bit
depth and up to 4 channels.
@param src filtering image with unsigned 8-bit or floating-point 32-bit depth and up to 4 channels.
@param dst destination image
@param sigmaSpatial \f${\sigma}_H\f$ parameter in the original article, it's similar to the sigma in the
coordinate space into bilateralFilter.
@param sigmaColor \f${\sigma}_r\f$ parameter in the original article, it's similar to the sigma in the
color space into bilateralFilter.
@param mode one form three modes DTF_NC, DTF_RF and DTF_IC which corresponds to three modes for
filtering 2D signals in the article.
@param numIters optional number of iterations used for filtering, 3 is quite enough.
@sa bilateralFilter, guidedFilter, amFilter
*/
CV_EXPORTS_W
void dtFilter(InputArray guide, InputArray src, OutputArray dst, double sigmaSpatial, double sigmaColor, int mode = DTF_NC, int numIters = 3);
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
/** @brief Interface for realizations of (Fast) Guided Filter.
For more details about this filter see @cite Kaiming10 @cite Kaiming15 .
*/
class CV_EXPORTS_W GuidedFilter : public Algorithm
{
public:
/** @brief Apply (Fast) Guided Filter to the filtering image.
@param src filtering image with any numbers of channels.
@param dst output image.
@param dDepth optional depth of the output image. dDepth can be set to -1, which will be equivalent
to src.depth().
*/
CV_WRAP virtual void filter(InputArray src, OutputArray dst, int dDepth = -1) = 0;
};
/** @brief Factory method, create instance of GuidedFilter and produce initialization routines.
@param guide guided image (or array of images) with up to 3 channels, if it have more then 3
channels then only first 3 channels will be used.
@param radius radius of Guided Filter.
@param eps regularization term of Guided Filter. \f${eps}^2\f$ is similar to the sigma in the color
space into bilateralFilter.
@param scale subsample factor of Fast Guided Filter, use a scale less than 1 to speeds up computation
with almost no visible degradation. (e.g. scale==0.5 shrinks the image by 2x inside the filter)
For more details about (Fast) Guided Filter parameters, see the original articles @cite Kaiming10 @cite Kaiming15 .
*/
CV_EXPORTS_W Ptr<GuidedFilter> createGuidedFilter(InputArray guide, int radius, double eps, double scale = 1.0);
/** @brief Simple one-line (Fast) Guided Filter call.
If you have multiple images to filter with the same guided image then use GuidedFilter interface to
avoid extra computations on initialization stage.
@param guide guided image (or array of images) with up to 3 channels, if it have more then 3
channels then only first 3 channels will be used.
@param src filtering image with any numbers of channels.
@param dst output image.
@param radius radius of Guided Filter.
@param eps regularization term of Guided Filter. \f${eps}^2\f$ is similar to the sigma in the color
space into bilateralFilter.
@param dDepth optional depth of the output image.
@param scale subsample factor of Fast Guided Filter, use a scale less than 1 to speeds up computation
with almost no visible degradation. (e.g. scale==0.5 shrinks the image by 2x inside the filter)
@sa bilateralFilter, dtFilter, amFilter */
CV_EXPORTS_W void guidedFilter(InputArray guide, InputArray src, OutputArray dst, int radius, double eps, int dDepth = -1, double scale = 1.0);
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
/** @brief Interface for Adaptive Manifold Filter realizations.
For more details about this filter see @cite Gastal12 and References_.
Below listed optional parameters which may be set up with Algorithm::set function.
- member double sigma_s = 16.0
Spatial standard deviation.
- member double sigma_r = 0.2
Color space standard deviation.
- member int tree_height = -1
Height of the manifold tree (default = -1 : automatically computed).
- member int num_pca_iterations = 1
Number of iterations to computed the eigenvector.
- member bool adjust_outliers = false
Specify adjust outliers using Eq. 9 or not.
- member bool use_RNG = true
Specify use random number generator to compute eigenvector or not.
*/
class CV_EXPORTS_W AdaptiveManifoldFilter : public Algorithm
{
public:
/** @brief Apply high-dimensional filtering using adaptive manifolds.
@param src filtering image with any numbers of channels.
@param dst output image.
@param joint optional joint (also called as guided) image with any numbers of channels.
*/
CV_WRAP virtual void filter(InputArray src, OutputArray dst, InputArray joint = noArray()) = 0;
CV_WRAP virtual void collectGarbage() = 0;
CV_WRAP static Ptr<AdaptiveManifoldFilter> create();
/** @see setSigmaS */
virtual double getSigmaS() const = 0;
/** @copybrief getSigmaS @see getSigmaS */
virtual void setSigmaS(double val) = 0;
/** @see setSigmaR */
virtual double getSigmaR() const = 0;
/** @copybrief getSigmaR @see getSigmaR */
virtual void setSigmaR(double val) = 0;
/** @see setTreeHeight */
virtual int getTreeHeight() const = 0;
/** @copybrief getTreeHeight @see getTreeHeight */
virtual void setTreeHeight(int val) = 0;
/** @see setPCAIterations */
virtual int getPCAIterations() const = 0;
/** @copybrief getPCAIterations @see getPCAIterations */
virtual void setPCAIterations(int val) = 0;
/** @see setAdjustOutliers */
virtual bool getAdjustOutliers() const = 0;
/** @copybrief getAdjustOutliers @see getAdjustOutliers */
virtual void setAdjustOutliers(bool val) = 0;
/** @see setUseRNG */
virtual bool getUseRNG() const = 0;
/** @copybrief getUseRNG @see getUseRNG */
virtual void setUseRNG(bool val) = 0;
};
/** @brief Factory method, create instance of AdaptiveManifoldFilter and produce some initialization routines.
@param sigma_s spatial standard deviation.
@param sigma_r color space standard deviation, it is similar to the sigma in the color space into
bilateralFilter.
@param adjust_outliers optional, specify perform outliers adjust operation or not, (Eq. 9) in the
original paper.
For more details about Adaptive Manifold Filter parameters, see the original article @cite Gastal12 .
@note Joint images with CV_8U and CV_16U depth converted to images with CV_32F depth and [0; 1]
color range before processing. Hence color space sigma sigma_r must be in [0; 1] range, unlike same
sigmas in bilateralFilter and dtFilter functions.
*/
CV_EXPORTS_W Ptr<AdaptiveManifoldFilter> createAMFilter(double sigma_s, double sigma_r, bool adjust_outliers = false);
/** @brief Simple one-line Adaptive Manifold Filter call.
@param joint joint (also called as guided) image or array of images with any numbers of channels.
@param src filtering image with any numbers of channels.
@param dst output image.
@param sigma_s spatial standard deviation.
@param sigma_r color space standard deviation, it is similar to the sigma in the color space into
bilateralFilter.
@param adjust_outliers optional, specify perform outliers adjust operation or not, (Eq. 9) in the
original paper.
@note Joint images with CV_8U and CV_16U depth converted to images with CV_32F depth and [0; 1]
color range before processing. Hence color space sigma sigma_r must be in [0; 1] range, unlike same
sigmas in bilateralFilter and dtFilter functions. @sa bilateralFilter, dtFilter, guidedFilter
*/
CV_EXPORTS_W void amFilter(InputArray joint, InputArray src, OutputArray dst, double sigma_s, double sigma_r, bool adjust_outliers = false);
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
/** @brief Applies the joint bilateral filter to an image.
@param joint Joint 8-bit or floating-point, 1-channel or 3-channel image.
@param src Source 8-bit or floating-point, 1-channel or 3-channel image with the same depth as joint
image.
@param dst Destination image of the same size and type as src .
@param d Diameter of each pixel neighborhood that is used during filtering. If it is non-positive,
it is computed from sigmaSpace .
@param sigmaColor Filter sigma in the color space. A larger value of the parameter means that
farther colors within the pixel neighborhood (see sigmaSpace ) will be mixed together, resulting in
larger areas of semi-equal color.
@param sigmaSpace Filter sigma in the coordinate space. A larger value of the parameter means that
farther pixels will influence each other as long as their colors are close enough (see sigmaColor ).
When d\>0 , it specifies the neighborhood size regardless of sigmaSpace . Otherwise, d is
proportional to sigmaSpace .
@param borderType
@note bilateralFilter and jointBilateralFilter use L1 norm to compute difference between colors.
@sa bilateralFilter, amFilter
*/
CV_EXPORTS_W
void jointBilateralFilter(InputArray joint, InputArray src, OutputArray dst, int d, double sigmaColor, double sigmaSpace, int borderType = BORDER_DEFAULT);
/** @brief Applies the bilateral texture filter to an image. It performs structure-preserving texture filter.
For more details about this filter see @cite Cho2014.
@param src Source image whose depth is 8-bit UINT or 32-bit FLOAT
@param dst Destination image of the same size and type as src.
@param fr Radius of kernel to be used for filtering. It should be positive integer
@param numIter Number of iterations of algorithm, It should be positive integer
@param sigmaAlpha Controls the sharpness of the weight transition from edges to smooth/texture regions, where
a bigger value means sharper transition. When the value is negative, it is automatically calculated.
@param sigmaAvg Range blur parameter for texture blurring. Larger value makes result to be more blurred. When the
value is negative, it is automatically calculated as described in the paper.
@sa rollingGuidanceFilter, bilateralFilter
*/
CV_EXPORTS_W
void bilateralTextureFilter(InputArray src, OutputArray dst, int fr = 3, int numIter = 1, double sigmaAlpha = -1., double sigmaAvg = -1.);
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
/** @brief Applies the rolling guidance filter to an image.
For more details, please see @cite zhang2014rolling
@param src Source 8-bit or floating-point, 1-channel or 3-channel image.
@param dst Destination image of the same size and type as src.
@param d Diameter of each pixel neighborhood that is used during filtering. If it is non-positive,
it is computed from sigmaSpace .
@param sigmaColor Filter sigma in the color space. A larger value of the parameter means that
farther colors within the pixel neighborhood (see sigmaSpace ) will be mixed together, resulting in
larger areas of semi-equal color.
@param sigmaSpace Filter sigma in the coordinate space. A larger value of the parameter means that
farther pixels will influence each other as long as their colors are close enough (see sigmaColor ).
When d\>0 , it specifies the neighborhood size regardless of sigmaSpace . Otherwise, d is
proportional to sigmaSpace .
@param numOfIter Number of iterations of joint edge-preserving filtering applied on the source image.
@param borderType
@note rollingGuidanceFilter uses jointBilateralFilter as the edge-preserving filter.
@sa jointBilateralFilter, bilateralFilter, amFilter
*/
CV_EXPORTS_W
void rollingGuidanceFilter(InputArray src, OutputArray dst, int d = -1, double sigmaColor = 25, double sigmaSpace = 3, int numOfIter = 4, int borderType = BORDER_DEFAULT);
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
/** @brief Interface for implementations of Fast Bilateral Solver.
For more details about this solver see @cite BarronPoole2016 .
*/
class CV_EXPORTS_W FastBilateralSolverFilter : public Algorithm
{
public:
/** @brief Apply smoothing operation to the source image.
@param src source image for filtering with unsigned 8-bit or signed 16-bit or floating-point 32-bit depth and up to 3 channels.
@param confidence confidence image with unsigned 8-bit or floating-point 32-bit confidence and 1 channel.
@param dst destination image.
@note Confidence images with CV_8U depth are expected to in [0, 255] and CV_32F in [0, 1] range.
*/
CV_WRAP virtual void filter(InputArray src, InputArray confidence, OutputArray dst) = 0;
};
/** @brief Factory method, create instance of FastBilateralSolverFilter and execute the initialization routines.
@param guide image serving as guide for filtering. It should have 8-bit depth and either 1 or 3 channels.
@param sigma_spatial parameter, that is similar to spatial space sigma (bandwidth) in bilateralFilter.
@param sigma_luma parameter, that is similar to luma space sigma (bandwidth) in bilateralFilter.
@param sigma_chroma parameter, that is similar to chroma space sigma (bandwidth) in bilateralFilter.
@param lambda smoothness strength parameter for solver.
@param num_iter number of iterations used for solver, 25 is usually enough.
@param max_tol convergence tolerance used for solver.
For more details about the Fast Bilateral Solver parameters, see the original paper @cite BarronPoole2016.
*/
CV_EXPORTS_W Ptr<FastBilateralSolverFilter> createFastBilateralSolverFilter(InputArray guide, double sigma_spatial, double sigma_luma, double sigma_chroma, double lambda = 128.0, int num_iter = 25, double max_tol = 1e-5);
/** @brief Simple one-line Fast Bilateral Solver filter call. If you have multiple images to filter with the same
guide then use FastBilateralSolverFilter interface to avoid extra computations.
@param guide image serving as guide for filtering. It should have 8-bit depth and either 1 or 3 channels.
@param src source image for filtering with unsigned 8-bit or signed 16-bit or floating-point 32-bit depth and up to 4 channels.
@param confidence confidence image with unsigned 8-bit or floating-point 32-bit confidence and 1 channel.
@param dst destination image.
@param sigma_spatial parameter, that is similar to spatial space sigma (bandwidth) in bilateralFilter.
@param sigma_luma parameter, that is similar to luma space sigma (bandwidth) in bilateralFilter.
@param sigma_chroma parameter, that is similar to chroma space sigma (bandwidth) in bilateralFilter.
@param lambda smoothness strength parameter for solver.
@param num_iter number of iterations used for solver, 25 is usually enough.
@param max_tol convergence tolerance used for solver.
For more details about the Fast Bilateral Solver parameters, see the original paper @cite BarronPoole2016.
@note Confidence images with CV_8U depth are expected to in [0, 255] and CV_32F in [0, 1] range.
*/
CV_EXPORTS_W void fastBilateralSolverFilter(InputArray guide, InputArray src, InputArray confidence, OutputArray dst, double sigma_spatial = 8, double sigma_luma = 8, double sigma_chroma = 8, double lambda = 128.0, int num_iter = 25, double max_tol = 1e-5);
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
/** @brief Interface for implementations of Fast Global Smoother filter.
For more details about this filter see @cite Min2014 and @cite Farbman2008 .
*/
class CV_EXPORTS_W FastGlobalSmootherFilter : public Algorithm
{
public:
/** @brief Apply smoothing operation to the source image.
@param src source image for filtering with unsigned 8-bit or signed 16-bit or floating-point 32-bit depth and up to 4 channels.
@param dst destination image.
*/
CV_WRAP virtual void filter(InputArray src, OutputArray dst) = 0;
};
/** @brief Factory method, create instance of FastGlobalSmootherFilter and execute the initialization routines.
@param guide image serving as guide for filtering. It should have 8-bit depth and either 1 or 3 channels.
@param lambda parameter defining the amount of regularization
@param sigma_color parameter, that is similar to color space sigma in bilateralFilter.
@param lambda_attenuation internal parameter, defining how much lambda decreases after each iteration. Normally,
it should be 0.25. Setting it to 1.0 may lead to streaking artifacts.
@param num_iter number of iterations used for filtering, 3 is usually enough.
For more details about Fast Global Smoother parameters, see the original paper @cite Min2014. However, please note that
there are several differences. Lambda attenuation described in the paper is implemented a bit differently so do not
expect the results to be identical to those from the paper; sigma_color values from the paper should be multiplied by 255.0 to
achieve the same effect. Also, in case of image filtering where source and guide image are the same, authors
propose to dynamically update the guide image after each iteration. To maximize the performance this feature
was not implemented here.
*/
CV_EXPORTS_W Ptr<FastGlobalSmootherFilter> createFastGlobalSmootherFilter(InputArray guide, double lambda, double sigma_color, double lambda_attenuation=0.25, int num_iter=3);
/** @brief Simple one-line Fast Global Smoother filter call. If you have multiple images to filter with the same
guide then use FastGlobalSmootherFilter interface to avoid extra computations.
@param guide image serving as guide for filtering. It should have 8-bit depth and either 1 or 3 channels.
@param src source image for filtering with unsigned 8-bit or signed 16-bit or floating-point 32-bit depth and up to 4 channels.
@param dst destination image.
@param lambda parameter defining the amount of regularization
@param sigma_color parameter, that is similar to color space sigma in bilateralFilter.
@param lambda_attenuation internal parameter, defining how much lambda decreases after each iteration. Normally,
it should be 0.25. Setting it to 1.0 may lead to streaking artifacts.
@param num_iter number of iterations used for filtering, 3 is usually enough.
*/
CV_EXPORTS_W void fastGlobalSmootherFilter(InputArray guide, InputArray src, OutputArray dst, double lambda, double sigma_color, double lambda_attenuation=0.25, int num_iter=3);
/** @brief Global image smoothing via L0 gradient minimization.
@param src source image for filtering with unsigned 8-bit or signed 16-bit or floating-point depth.
@param dst destination image.
@param lambda parameter defining the smooth term weight.
@param kappa parameter defining the increasing factor of the weight of the gradient data term.
For more details about L0 Smoother, see the original paper @cite xu2011image.
*/
CV_EXPORTS_W void l0Smooth(InputArray src, OutputArray dst, double lambda = 0.02, double kappa = 2.0);
//! @}
}
}
#endif
#endif
@@ -0,0 +1,201 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#ifndef __OPENCV_EDGEBOXES_HPP__
#define __OPENCV_EDGEBOXES_HPP__
#include <opencv2/core.hpp>
namespace cv
{
namespace ximgproc
{
//! @addtogroup ximgproc_edgeboxes
//! @{
// bounding box data structures
typedef struct
{
int x, y, w, h;
float score;
} Box;
typedef std::vector<Box> Boxes;
/** @brief Class implementing EdgeBoxes algorithm from @cite ZitnickECCV14edgeBoxes :
*/
class CV_EXPORTS_W EdgeBoxes : public Algorithm
{
public:
/** @brief Returns array containing proposal boxes.
@param edge_map edge image.
@param orientation_map orientation map.
@param boxes proposal boxes.
@param scores of the proposal boxes, provided a vector of float types.
*/
CV_WRAP virtual void getBoundingBoxes(InputArray edge_map, InputArray orientation_map, CV_OUT std::vector<Rect> &boxes, OutputArray scores = noArray()) = 0;
/** @brief Returns the step size of sliding window search.
*/
CV_WRAP virtual float getAlpha() const = 0;
/** @brief Sets the step size of sliding window search.
*/
CV_WRAP virtual void setAlpha(float value) = 0;
/** @brief Returns the nms threshold for object proposals.
*/
CV_WRAP virtual float getBeta() const = 0;
/** @brief Sets the nms threshold for object proposals.
*/
CV_WRAP virtual void setBeta(float value) = 0;
/** @brief Returns adaptation rate for nms threshold.
*/
CV_WRAP virtual float getEta() const = 0;
/** @brief Sets the adaptation rate for nms threshold.
*/
CV_WRAP virtual void setEta(float value) = 0;
/** @brief Returns the min score of boxes to detect.
*/
CV_WRAP virtual float getMinScore() const = 0;
/** @brief Sets the min score of boxes to detect.
*/
CV_WRAP virtual void setMinScore(float value) = 0;
/** @brief Returns the max number of boxes to detect.
*/
CV_WRAP virtual int getMaxBoxes() const = 0;
/** @brief Sets max number of boxes to detect.
*/
CV_WRAP virtual void setMaxBoxes(int value) = 0;
/** @brief Returns the edge min magnitude.
*/
CV_WRAP virtual float getEdgeMinMag() const = 0;
/** @brief Sets the edge min magnitude.
*/
CV_WRAP virtual void setEdgeMinMag(float value) = 0;
/** @brief Returns the edge merge threshold.
*/
CV_WRAP virtual float getEdgeMergeThr() const = 0;
/** @brief Sets the edge merge threshold.
*/
CV_WRAP virtual void setEdgeMergeThr(float value) = 0;
/** @brief Returns the cluster min magnitude.
*/
CV_WRAP virtual float getClusterMinMag() const = 0;
/** @brief Sets the cluster min magnitude.
*/
CV_WRAP virtual void setClusterMinMag(float value) = 0;
/** @brief Returns the max aspect ratio of boxes.
*/
CV_WRAP virtual float getMaxAspectRatio() const = 0;
/** @brief Sets the max aspect ratio of boxes.
*/
CV_WRAP virtual void setMaxAspectRatio(float value) = 0;
/** @brief Returns the minimum area of boxes.
*/
CV_WRAP virtual float getMinBoxArea() const = 0;
/** @brief Sets the minimum area of boxes.
*/
CV_WRAP virtual void setMinBoxArea(float value) = 0;
/** @brief Returns the affinity sensitivity.
*/
CV_WRAP virtual float getGamma() const = 0;
/** @brief Sets the affinity sensitivity
*/
CV_WRAP virtual void setGamma(float value) = 0;
/** @brief Returns the scale sensitivity.
*/
CV_WRAP virtual float getKappa() const = 0;
/** @brief Sets the scale sensitivity.
*/
CV_WRAP virtual void setKappa(float value) = 0;
};
/** @brief Creates a Edgeboxes
@param alpha step size of sliding window search.
@param beta nms threshold for object proposals.
@param eta adaptation rate for nms threshold.
@param minScore min score of boxes to detect.
@param maxBoxes max number of boxes to detect.
@param edgeMinMag edge min magnitude. Increase to trade off accuracy for speed.
@param edgeMergeThr edge merge threshold. Increase to trade off accuracy for speed.
@param clusterMinMag cluster min magnitude. Increase to trade off accuracy for speed.
@param maxAspectRatio max aspect ratio of boxes.
@param minBoxArea minimum area of boxes.
@param gamma affinity sensitivity.
@param kappa scale sensitivity.
*/
CV_EXPORTS_W Ptr<EdgeBoxes>
createEdgeBoxes(float alpha=0.65f,
float beta=0.75f,
float eta=1,
float minScore=0.01f,
int maxBoxes=10000,
float edgeMinMag=0.1f,
float edgeMergeThr=0.5f,
float clusterMinMag=0.5f,
float maxAspectRatio=3,
float minBoxArea=1000,
float gamma=2,
float kappa=1.5f);
//! @}
}
}
#endif /* __OPENCV_EDGEBOXES_HPP__ */
@@ -0,0 +1,33 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifndef __OPENCV_EDGEPRESERVINGFILTER_HPP__
#define __OPENCV_EDGEPRESERVINGFILTER_HPP__
#include <opencv2/core.hpp>
namespace cv { namespace ximgproc {
//! @addtogroup ximgproc
//! @{
/**
* @brief Smoothes an image using the Edge-Preserving filter.
*
* The function smoothes Gaussian noise as well as salt & pepper noise.
* For more details about this implementation, please see
* [ReiWoe18] Reich, S. and Wörgötter, F. and Dellen, B. (2018). A Real-Time Edge-Preserving Denoising Filter. Proceedings of the 13th International Joint Conference on Computer Vision, Imaging and Computer Graphics Theory and Applications (VISIGRAPP): Visapp, 85-94, 4. DOI: 10.5220/0006509000850094.
*
* @param src Source 8-bit 3-channel image.
* @param dst Destination image of the same size and type as src.
* @param d Diameter of each pixel neighborhood that is used during filtering. Must be greater or equal 3.
* @param threshold Threshold, which distinguishes between noise, outliers, and data.
*/
CV_EXPORTS_W void edgePreservingFilter( InputArray src, OutputArray dst, int d, double threshold );
//! @}
}} // namespace
#endif
@@ -0,0 +1,82 @@
/*
By downloading, copying, installing or using the software you agree to this license.
If you do not agree to this license, do not download, install,
copy or use the software.
License Agreement
For Open Source Computer Vision Library
(3-clause BSD License)
Copyright (C) 2000-2015, Intel Corporation, all rights reserved.
Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
Copyright (C) 2009-2015, NVIDIA Corporation, all rights reserved.
Copyright (C) 2010-2013, Advanced Micro Devices, Inc., all rights reserved.
Copyright (C) 2015, OpenCV Foundation, all rights reserved.
Copyright (C) 2015, Itseez Inc., all rights reserved.
Third party copyrights are property of their respective owners.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the names of the copyright holders nor the names of the contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
This software is provided by the copyright holders and contributors "as is" and
any express or implied warranties, including, but not limited to, the implied
warranties of merchantability and fitness for a particular purpose are disclaimed.
In no event shall copyright holders or contributors be liable for any direct,
indirect, incidental, special, exemplary, or consequential damages
(including, but not limited to, procurement of substitute goods or services;
loss of use, data, or profits; or business interruption) however caused
and on any theory of liability, whether in contract, strict liability,
or tort (including negligence or otherwise) arising in any way out of
the use of this software, even if advised of the possibility of such damage.
Algorithmic details of this algorithm can be found at:
* O. Green, Y. Birk, "A Computationally Efficient Algorithm for the 2D Covariance Method", ACM/IEEE International Conference on High Performance Computing, Networking, Storage and Analysis, Denver, Colorado, 2013
A previous and less efficient version of the algorithm can be found:
* O. Green, L. David, A. Galperin, Y. Birk, "Efficient parallel computation of the estimated covariance matrix", arXiv, 2013
*/
#ifndef __OPENCV_ESTIMATECOVARIANCE_HPP__
#define __OPENCV_ESTIMATECOVARIANCE_HPP__
#ifdef __cplusplus
#include <opencv2/core.hpp>
namespace cv
{
namespace ximgproc
{
/** @brief Computes the estimated covariance matrix of an image using the sliding
window forumlation.
@param src The source image. Input image must be of a complex type.
@param dst The destination estimated covariance matrix. Output matrix will be size (windowRows*windowCols, windowRows*windowCols).
@param windowRows The number of rows in the window.
@param windowCols The number of cols in the window.
The window size parameters control the accuracy of the estimation.
The sliding window moves over the entire image from the top-left corner
to the bottom right corner. Each location of the window represents a sample.
If the window is the size of the image, then this gives the exact covariance matrix.
For all other cases, the sizes of the window will impact the number of samples
and the number of elements in the estimated covariance matrix.
*/
CV_EXPORTS_W void covarianceEstimation(InputArray src, OutputArray dst, int windowRows, int windowCols);
}
}
#endif
#endif
@@ -0,0 +1,163 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2015, Smart Engines Ltd, all rights reserved.
// Copyright (C) 2015, Institute for Information Transmission Problems of the Russian Academy of Sciences (Kharkevich Institute), all rights reserved.
// Copyright (C) 2015, Dmitry Nikolaev, Simon Karpenko, Michail Aliev, Elena Kuznetsova, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#ifndef __OPENCV_FAST_HOUGH_TRANSFORM_HPP__
#define __OPENCV_FAST_HOUGH_TRANSFORM_HPP__
#ifdef __cplusplus
#include "opencv2/core.hpp"
namespace cv { namespace ximgproc {
/**
* @brief Specifies the part of Hough space to calculate
* @details The enum specifies the part of Hough space to calculate. Each
* member specifies primarily direction of lines (horizontal or vertical)
* and the direction of angle changes.
* Direction of angle changes is from multiples of 90 to odd multiples of 45.
* The image considered to be written top-down and left-to-right.
* Angles are started from vertical line and go clockwise.
* Separate quarters and halves are written in orientation they should be in
* full Hough space.
*/
enum AngleRangeOption
{
ARO_0_45 = 0, //< Vertical primarily direction and clockwise angle changes
ARO_45_90 = 1, //< Horizontal primarily direction and counterclockwise angle changes
ARO_90_135 = 2, //< Horizontal primarily direction and clockwise angle changes
ARO_315_0 = 3, //< Vertical primarily direction and counterclockwise angle changes
ARO_315_45 = 4, //< Vertical primarily direction
ARO_45_135 = 5, //< Horizontal primarily direction
ARO_315_135 = 6, //< Full set of directions
ARO_CTR_HOR = 7, //< 90 +/- atan(0.5), interval approximately from 64.5 to 116.5 degrees.
//< It is used for calculating Fast Hough Transform for images skewed by atan(0.5).
ARO_CTR_VER = 8 //< +/- atan(0.5), interval approximately from 333.5(-26.5) to 26.5 degrees
//< It is used for calculating Fast Hough Transform for images skewed by atan(0.5).
};
/**
* @brief Specifies binary operations.
* @details The enum specifies binary operations, that is such ones which involve
* two operands. Formally, a binary operation @f$ f @f$ on a set @f$ S @f$
* is a binary relation that maps elements of the Cartesian product
* @f$ S \times S @f$ to @f$ S @f$:
* @f[ f: S \times S \to S @f]
*/
enum HoughOp
{
FHT_MIN = 0, //< Binary minimum operation. The constant specifies the binary minimum operation
//< @f$ f @f$ that is defined as follows: @f[ f(x, y) = \min(x, y) @f]
FHT_MAX = 1, //< Binary maximum operation. The constant specifies the binary maximum operation
//< @f$ f @f$ that is defined as follows: @f[ f(x, y) = \max(x, y) @f]
FHT_ADD = 2, //< Binary addition operation. The constant specifies the binary addition operation
//< @f$ f @f$ that is defined as follows: @f[ f(x, y) = x + y @f]
FHT_AVE = 3 //< Binary average operation. The constant specifies the binary average operation
//< @f$ f @f$ that is defined as follows: @f[ f(x, y) = \frac{x + y}{2} @f]
};
/**
* @brief Specifies to do or not to do skewing of Hough transform image
* @details The enum specifies to do or not to do skewing of Hough transform image
* so it would be no cycling in Hough transform image through borders of image.
*/
enum HoughDeskewOption
{
HDO_RAW = 0, //< Use raw cyclic image
HDO_DESKEW = 1 //< Prepare deskewed image
};
/**
* @brief Specifies the degree of rules validation.
* @details The enum specifies the degree of rules validation. This can be used,
* for example, to choose a proper way of input arguments validation.
*/
typedef enum {
RO_STRICT = 0x00, ///< Validate each rule in a proper way.
RO_IGNORE_BORDERS = 0x01, ///< Skip validations of image borders.
} RulesOption;
/**
* @brief Calculates 2D Fast Hough transform of an image.
* @param dst The destination image, result of transformation.
* @param src The source (input) image.
* @param dstMatDepth The depth of destination image
* @param op The operation to be applied, see cv::HoughOp
* @param angleRange The part of Hough space to calculate, see cv::AngleRangeOption
* @param makeSkew Specifies to do or not to do image skewing, see cv::HoughDeskewOption
*
* The function calculates the fast Hough transform for full, half or quarter
* range of angles.
*/
CV_EXPORTS_W void FastHoughTransform( InputArray src,
OutputArray dst,
int dstMatDepth,
int angleRange = ARO_315_135,
int op = FHT_ADD,
int makeSkew = HDO_DESKEW );
/**
* @brief Calculates coordinates of line segment corresponded by point in Hough space.
* @param houghPoint Point in Hough space.
* @param srcImgInfo The source (input) image of Hough transform.
* @param angleRange The part of Hough space where point is situated, see cv::AngleRangeOption
* @param makeSkew Specifies to do or not to do image skewing, see cv::HoughDeskewOption
* @param rules Specifies strictness of line segment calculating, see cv::RulesOption
* @retval [Vec4i] Coordinates of line segment corresponded by point in Hough space.
* @remarks If rules parameter set to RO_STRICT
then returned line cut along the border of source image.
* @remarks If rules parameter set to RO_WEAK then in case of point, which belongs
the incorrect part of Hough image, returned line will not intersect source image.
*
* The function calculates coordinates of line segment corresponded by point in Hough space.
*/
CV_EXPORTS_W Vec4i HoughPoint2Line(const Point &houghPoint,
InputArray srcImgInfo,
int angleRange = ARO_315_135,
int makeSkew = HDO_DESKEW,
int rules = RO_IGNORE_BORDERS );
} }// namespace cv::ximgproc
#endif //__cplusplus
#endif //__OPENCV_FAST_HOUGH_TRANSFORM_HPP__
@@ -0,0 +1,79 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifndef __OPENCV_FAST_LINE_DETECTOR_HPP__
#define __OPENCV_FAST_LINE_DETECTOR_HPP__
#include <opencv2/core.hpp>
namespace cv
{
namespace ximgproc
{
//! @addtogroup ximgproc_fast_line_detector
//! @{
/** @brief Class implementing the FLD (Fast Line Detector) algorithm described
in @cite Lee14 .
*/
//! @include samples/fld_lines.cpp
class CV_EXPORTS_W FastLineDetector : public Algorithm
{
public:
/** @example fld_lines.cpp
An example using the FastLineDetector
*/
/** @brief Finds lines in the input image.
This is the output of the default parameters of the algorithm on the above
shown image.
![image](pics/corridor_fld.jpg)
@param image A grayscale (CV_8UC1) input image. If only a roi needs to be
selected, use: `fld_ptr-\>detect(image(roi), lines, ...);
lines += Scalar(roi.x, roi.y, roi.x, roi.y);`
@param lines A vector of Vec4f elements specifying the beginning
and ending point of a line. Where Vec4f is (x1, y1, x2, y2), point
1 is the start, point 2 - end. Returned lines are directed so that the
brighter side is on their left.
*/
CV_WRAP virtual void detect(InputArray image, OutputArray lines) = 0;
/** @brief Draws the line segments on a given image.
@param image The image, where the lines will be drawn. Should be bigger
or equal to the image, where the lines were found.
@param lines A vector of the lines that needed to be drawn.
@param draw_arrow If true, arrow heads will be drawn.
@param linecolor Line color.
@param linethickness Line thickness.
*/
CV_WRAP virtual void drawSegments(InputOutputArray image, InputArray lines,
bool draw_arrow = false, Scalar linecolor = Scalar(0, 0, 255), int linethickness = 1) = 0;
virtual ~FastLineDetector() { }
};
/** @brief Creates a smart pointer to a FastLineDetector object and initializes it
@param length_threshold Segment shorter than this will be discarded
@param distance_threshold A point placed from a hypothesis line
segment farther than this will be regarded as an outlier
@param canny_th1 First threshold for hysteresis procedure in Canny()
@param canny_th2 Second threshold for hysteresis procedure in Canny()
@param canny_aperture_size Aperturesize for the sobel operator in Canny().
If zero, Canny() is not applied and the input image is taken as an edge image.
@param do_merge If true, incremental merging of segments will be performed
*/
CV_EXPORTS_W Ptr<FastLineDetector> createFastLineDetector(
int length_threshold = 10, float distance_threshold = 1.414213562f,
double canny_th1 = 50.0, double canny_th2 = 50.0, int canny_aperture_size = 3,
bool do_merge = false);
//! @} ximgproc_fast_line_detector
}
}
#endif
@@ -0,0 +1,38 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifndef __OPENCV_FIND_ELLIPSES_HPP__
#define __OPENCV_FIND_ELLIPSES_HPP__
#include <opencv2/core.hpp>
namespace cv {
namespace ximgproc {
//! @addtogroup ximgproc
//! @{
/**
@brief Finds ellipses fastly in an image using projective invariant pruning.
*
* The function detects ellipses in images using projective invariant pruning.
* For more details about this implementation, please see @cite jia2017fast
* Jia, Qi et al, (2017).
* A Fast Ellipse Detector using Projective Invariant Pruning. IEEE Transactions on Image Processing.
*
@param image input image, could be gray or color.
@param ellipses output vector of found ellipses. each vector is encoded as five float $x, y, a, b, radius, score$.
@param scoreThreshold float, the threshold of ellipse score.
@param reliabilityThreshold float, the threshold of reliability.
@param centerDistanceThreshold float, the threshold of center distance.
*/
CV_EXPORTS_W void findEllipses(
InputArray image, OutputArray ellipses,
float scoreThreshold = 0.7f, float reliabilityThreshold = 0.5f,
float centerDistanceThreshold = 0.05f
);
//! @} ximgproc
}
}
#endif
@@ -0,0 +1,119 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifndef __OPENCV_FOURIERDESCRIPTORS_HPP__
#define __OPENCV_FOURIERDESCRIPTORS_HPP__
#include <opencv2/core.hpp>
namespace cv {
namespace ximgproc {
//! @addtogroup ximgproc_fourier
//! @{
/** @brief Class for ContourFitting algorithms.
ContourFitting match two contours \f$ z_a \f$ and \f$ z_b \f$ minimizing distance
\f[ d(z_a,z_b)=\sum (a_n - s b_n e^{j(n \alpha +\phi )})^2 \f] where \f$ a_n \f$ and \f$ b_n \f$ are Fourier descriptors of \f$ z_a \f$ and \f$ z_b \f$ and s is a scaling factor and \f$ \phi \f$ is angle rotation and \f$ \alpha \f$ is starting point factor adjustement
*/
class CV_EXPORTS_W ContourFitting : public Algorithm
{
int ctrSize;
int fdSize;
std::vector<std::complex<double> > b;
std::vector<std::complex<double> > a;
std::vector<double> frequence;
std::vector<double> rho, psi;
void frequencyInit();
void fAlpha(double x, double &fn, double &df);
double distance(std::complex<double> r, double alpha);
double newtonRaphson(double x1, double x2);
public:
/** @brief Fit two closed curves using fourier descriptors. More details in @cite PersoonFu1977 and @cite BergerRaghunathan1998
* @param ctr number of Fourier descriptors equal to number of contour points after resampling.
* @param fd Contour defining second shape (Target).
*/
ContourFitting(int ctr=1024,int fd=16):ctrSize(ctr),fdSize(fd){};
/** @brief Fit two closed curves using fourier descriptors. More details in @cite PersoonFu1977 and @cite BergerRaghunathan1998
@param src Contour defining first shape.
@param dst Contour defining second shape (Target).
@param alphaPhiST : \f$ \alpha \f$=alphaPhiST(0,0), \f$ \phi \f$=alphaPhiST(0,1) (in radian), s=alphaPhiST(0,2), Tx=alphaPhiST(0,3), Ty=alphaPhiST(0,4) rotation center
@param dist distance between src and dst after matching.
@param fdContour false then src and dst are contours and true src and dst are fourier descriptors.
*/
void estimateTransformation(InputArray src, InputArray dst, OutputArray alphaPhiST, double *dist = 0, bool fdContour = false);
/** @brief Fit two closed curves using fourier descriptors. More details in @cite PersoonFu1977 and @cite BergerRaghunathan1998
@param src Contour defining first shape.
@param dst Contour defining second shape (Target).
@param alphaPhiST : \f$ \alpha \f$=alphaPhiST(0,0), \f$ \phi \f$=alphaPhiST(0,1) (in radian), s=alphaPhiST(0,2), Tx=alphaPhiST(0,3), Ty=alphaPhiST(0,4) rotation center
@param dist distance between src and dst after matching.
@param fdContour false then src and dst are contours and true src and dst are fourier descriptors.
*/
CV_WRAP void estimateTransformation(InputArray src, InputArray dst, OutputArray alphaPhiST, CV_OUT double &dist , bool fdContour = false);
/** @brief set number of Fourier descriptors used in estimateTransformation
@param n number of Fourier descriptors equal to number of contour points after resampling.
*/
CV_WRAP void setCtrSize(int n);
/** @brief set number of Fourier descriptors when estimateTransformation used vector<Point>
@param n number of fourier descriptors used for optimal curve matching.
*/
CV_WRAP void setFDSize(int n);
/**
@returns number of fourier descriptors
*/
CV_WRAP int getCtrSize() { return ctrSize; };
/**
@returns number of fourier descriptors used for optimal curve matching
*/
CV_WRAP int getFDSize() { return fdSize; };
};
/**
* @brief Fourier descriptors for planed closed curves
*
* For more details about this implementation, please see @cite PersoonFu1977
*
* @param src contour type vector<Point> , vector<Point2f> or vector<Point2d>
* @param dst Mat of type CV_64FC2 and nbElt rows A VERIFIER
* @param nbElt number of rows in dst or getOptimalDFTSize rows if nbElt=-1
* @param nbFD number of FD return in dst dst = [FD(1...nbFD/2) FD(nbFD/2-nbElt+1...:nbElt)]
*
*/
CV_EXPORTS_W void fourierDescriptor(InputArray src, OutputArray dst, int nbElt=-1,int nbFD=-1);
/**
* @brief transform a contour
*
* @param src contour or Fourier Descriptors if fd is true
* @param t transform Mat given by estimateTransformation
* @param dst Mat of type CV_64FC2 and nbElt rows
* @param fdContour true src are Fourier Descriptors. fdContour false src is a contour
*
*/
CV_EXPORTS_W void transformFD(InputArray src, InputArray t,OutputArray dst, bool fdContour=true);
/**
* @brief Contour sampling .
*
* @param src contour type vector<Point> , vector<Point2f> or vector<Point2d>
* @param out Mat of type CV_64FC2 and nbElt rows
* @param nbElt number of points in out contour
*
*/
CV_EXPORTS_W void contourSampling(InputArray src, OutputArray out, int nbElt);
/**
* @brief create ContourFitting algorithm object
*
* @param ctr number of Fourier descriptors equal to number of contour points after resampling.
* @param fd Contour defining second shape (Target).
*/
CV_EXPORTS_W Ptr<ContourFitting> createContourFitting(int ctr = 1024, int fd = 16);
//! @} ximgproc_fourier
}
}
#endif
@@ -0,0 +1,157 @@
/*********************************************************************
* Software License Agreement (BSD License)
*
* Copyright (c) 2014, 2015
* Zhengqin Li <li-zq12 at mails dot tsinghua dot edu dot cn>
* Jiansheng Chen <jschenthu at mail dot tsinghua dot edu dot cn>
* Tsinghua University
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*********************************************************************/
/*
"Superpixel Segmentation using Linear Spectral Clustering"
Zhengqin Li, Jiansheng Chen, IEEE Conference on Computer Vision and Pattern
Recognition (CVPR), Jun. 2015
OpenCV port by: Cristian Balint <cristian dot balint at gmail dot com>
*/
#ifndef __OPENCV_LSC_HPP__
#define __OPENCV_LSC_HPP__
#ifdef __cplusplus
#include <opencv2/core.hpp>
namespace cv
{
namespace ximgproc
{
//! @addtogroup ximgproc_superpixel
//! @{
/** @brief Class implementing the LSC (Linear Spectral Clustering) superpixels
algorithm described in @cite LiCVPR2015LSC.
LSC (Linear Spectral Clustering) produces compact and uniform superpixels with low
computational costs. Basically, a normalized cuts formulation of the superpixel
segmentation is adopted based on a similarity metric that measures the color
similarity and space proximity between image pixels. LSC is of linear computational
complexity and high memory efficiency and is able to preserve global properties of images
*/
class CV_EXPORTS_W SuperpixelLSC : public Algorithm
{
public:
/** @brief Calculates the actual amount of superpixels on a given segmentation computed
and stored in SuperpixelLSC object.
*/
CV_WRAP virtual int getNumberOfSuperpixels() const = 0;
/** @brief Calculates the superpixel segmentation on a given image with the initialized
parameters in the SuperpixelLSC object.
This function can be called again without the need of initializing the algorithm with
createSuperpixelLSC(). This save the computational cost of allocating memory for all the
structures of the algorithm.
@param num_iterations Number of iterations. Higher number improves the result.
The function computes the superpixels segmentation of an image with the parameters initialized
with the function createSuperpixelLSC(). The algorithms starts from a grid of superpixels and
then refines the boundaries by proposing updates of edges boundaries.
*/
CV_WRAP virtual void iterate( int num_iterations = 10 ) = 0;
/** @brief Returns the segmentation labeling of the image.
Each label represents a superpixel, and each pixel is assigned to one superpixel label.
@param labels_out Return: A CV_32SC1 integer array containing the labels of the superpixel
segmentation. The labels are in the range [0, getNumberOfSuperpixels()].
The function returns an image with the labels of the superpixel segmentation. The labels are in
the range [0, getNumberOfSuperpixels()].
*/
CV_WRAP virtual void getLabels( OutputArray labels_out ) const = 0;
/** @brief Returns the mask of the superpixel segmentation stored in SuperpixelLSC object.
@param image Return: CV_8U1 image mask where -1 indicates that the pixel is a superpixel border,
and 0 otherwise.
@param thick_line If false, the border is only one pixel wide, otherwise all pixels at the border
are masked.
The function return the boundaries of the superpixel segmentation.
*/
CV_WRAP virtual void getLabelContourMask( OutputArray image, bool thick_line = true ) const = 0;
/** @brief Enforce label connectivity.
@param min_element_size The minimum element size in percents that should be absorbed into a bigger
superpixel. Given resulted average superpixel size valid value should be in 0-100 range, 25 means
that less then a quarter sized superpixel should be absorbed, this is default.
The function merge component that is too small, assigning the previously found adjacent label
to this component. Calling this function may change the final number of superpixels.
*/
CV_WRAP virtual void enforceLabelConnectivity( int min_element_size = 25 ) = 0;
};
/** @brief Class implementing the LSC (Linear Spectral Clustering) superpixels
@param image Image to segment
@param region_size Chooses an average superpixel size measured in pixels
@param ratio Chooses the enforcement of superpixel compactness factor of superpixel
The function initializes a SuperpixelLSC object for the input image. It sets the parameters of
superpixel algorithm, which are: region_size and ruler. It preallocate some buffers for future
computing iterations over the given image. An example of LSC is ilustrated in the following picture.
For enanched results it is recommended for color images to preprocess image with little gaussian blur
with a small 3 x 3 kernel and additional conversion into CieLAB color space.
![image](pics/superpixels_lsc.png)
*/
CV_EXPORTS_W Ptr<SuperpixelLSC> createSuperpixelLSC( InputArray image, int region_size = 10, float ratio = 0.075f );
//! @}
}
}
#endif
#endif
@@ -0,0 +1,69 @@
/*
* By downloading, copying, installing or using the software you agree to this license.
* If you do not agree to this license, do not download, install,
* copy or use the software.
*
*
* License Agreement
* For Open Source Computer Vision Library
* (3 - clause BSD License)
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met :
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and / or other materials provided with the distribution.
*
* * Neither the names of the copyright holders nor the names of the contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* This software is provided by the copyright holders and contributors "as is" and
* any express or implied warranties, including, but not limited to, the implied
* warranties of merchantability and fitness for a particular purpose are disclaimed.
* In no event shall copyright holders or contributors be liable for any direct,
* indirect, incidental, special, exemplary, or consequential damages
* (including, but not limited to, procurement of substitute goods or services;
* loss of use, data, or profits; or business interruption) however caused
* and on any theory of liability, whether in contract, strict liability,
* or tort(including negligence or otherwise) arising in any way out of
* the use of this software, even if advised of the possibility of such damage.
*/
#ifndef __OPENCV_PAILLOUFILTER_HPP__
#define __OPENCV_PAILLOUFILTER_HPP__
#ifdef __cplusplus
#include <opencv2/core.hpp>
namespace cv {
namespace ximgproc {
//! @addtogroup ximgproc_filters
//! @{
/**
* @brief Applies Paillou filter to an image.
*
* For more details about this implementation, please see @cite paillou1997detecting
*
* @param op Source CV_8U(S) or CV_16U(S), 1-channel or 3-channels image.
* @param _dst result CV_32F image with same number of channel than op.
* @param omega double see paper
* @param alpha double see paper
*
* @sa GradientPaillouX, GradientPaillouY
*/
CV_EXPORTS void GradientPaillouY(InputArray op, OutputArray _dst, double alpha, double omega);
CV_EXPORTS void GradientPaillouX(InputArray op, OutputArray _dst, double alpha, double omega);
//! @}
}
}
#endif
#endif
@@ -0,0 +1,34 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifndef __OPENCV_PEILIN_HPP__
#define __OPENCV_PEILIN_HPP__
#include <opencv2/core.hpp>
namespace cv { namespace ximgproc {
//! @addtogroup ximgproc
//! @{
/**
* @brief Calculates an affine transformation that normalize given image using Pei&Lin Normalization.
*
* Assume given image \f$I=T(\bar{I})\f$ where \f$\bar{I}\f$ is a normalized image and \f$T\f$ is an affine transformation distorting this image by translation, rotation, scaling and skew.
* The function returns an affine transformation matrix corresponding to the transformation \f$T^{-1}\f$ described in [PeiLin95].
* For more details about this implementation, please see
* [PeiLin95] Soo-Chang Pei and Chao-Nan Lin. Image normalization for pattern recognition. Image and Vision Computing, Vol. 13, N.10, pp. 711-723, 1995.
*
* @param I Given transformed image.
* @return Transformation matrix corresponding to inversed image transformation
*/
CV_EXPORTS Matx23d PeiLinNormalization ( InputArray I );
/** @overload */
CV_EXPORTS_W void PeiLinNormalization ( InputArray I, OutputArray T );
//! @}
}} // namespace
#endif
@@ -0,0 +1,40 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifndef __OPENCV_RADON_TRANSFORM_HPP__
#define __OPENCV_RADON_TRANSFORM_HPP__
#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
namespace cv { namespace ximgproc {
/**
* @brief Calculate Radon Transform of an image.
* @param src The source (input) image.
* @param dst The destination image, result of transformation.
* @param theta Angle resolution of the transform in degrees.
* @param start_angle Start angle of the transform in degrees.
* @param end_angle End angle of the transform in degrees.
* @param crop Crop the source image into a circle.
* @param norm Normalize the output Mat to grayscale and convert type to CV_8U
*
* This function calculates the Radon Transform of a given image in any range.
* See https://engineering.purdue.edu/~malcolm/pct/CTI_Ch03.pdf for detail.
* If the input type is CV_8U, the output will be CV_32S.
* If the input type is CV_32F or CV_64F, the output will be CV_64F
* The output size will be num_of_integral x src_diagonal_length.
* If crop is selected, the input image will be crop into square then circle,
* and output size will be num_of_integral x min_edge.
*
*/
CV_EXPORTS_W void RadonTransform(InputArray src,
OutputArray dst,
double theta = 1,
double start_angle = 0,
double end_angle = 180,
bool crop = false,
bool norm = false);
} }
#endif
@@ -0,0 +1,53 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
/*
Ridge Detection Filter.
OpenCV port by : Kushal Vyas (@kushalvyas), Venkatesh Vijaykumar(@venkateshvijaykumar)
Adapted from Niki Estner's explanation of RidgeFilter.
*/
#ifndef __OPENCV_XIMGPROC_RIDGEFILTER_HPP__
#define __OPENCV_XIMGPROC_RIDGEFILTER_HPP__
#include <opencv2/core.hpp>
namespace cv { namespace ximgproc {
//! @addtogroup ximgproc_filters
//! @{
/** @brief Applies Ridge Detection Filter to an input image.
Implements Ridge detection similar to the one in [Mathematica](http://reference.wolfram.com/language/ref/RidgeFilter.html)
using the eigen values from the Hessian Matrix of the input image using Sobel Derivatives.
Additional refinement can be done using Skeletonization and Binarization. Adapted from @cite segleafvein and @cite M_RF
*/
class CV_EXPORTS_W RidgeDetectionFilter : public Algorithm
{
public:
/**
@brief Create pointer to the Ridge detection filter.
@param ddepth Specifies output image depth. Defualt is CV_32FC1
@param dx Order of derivative x, default is 1
@param dy Order of derivative y, default is 1
@param ksize Sobel kernel size , default is 3
@param out_dtype Converted format for output, default is CV_8UC1
@param scale Optional scale value for derivative values, default is 1
@param delta Optional bias added to output, default is 0
@param borderType Pixel extrapolation method, default is BORDER_DEFAULT
@see Sobel, threshold, getStructuringElement, morphologyEx.( for additional refinement)
*/
CV_WRAP static Ptr<RidgeDetectionFilter> create(int ddepth = CV_32FC1, int dx=1, int dy=1, int ksize = 3, int out_dtype=CV_8UC1, double scale = 1, double delta = 0, int borderType = BORDER_DEFAULT);
/**
@brief Apply Ridge detection filter on input image.
@param _img InputArray as supported by Sobel. img can be 1-Channel or 3-Channels.
@param out OutputAray of structure as RidgeDetectionFilter::ddepth. Output image with ridges.
*/
CV_WRAP virtual void getRidgeFilteredImage(InputArray _img, OutputArray out) = 0;
};
//! @}
}} // namespace
#endif
@@ -0,0 +1,121 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifndef __OPENCV_RUN_LENGTH_MORPHOLOGY_HPP__
#define __OPENCV_RUN_LENGTH_MORPHOLOGY_HPP__
#include <opencv2/core.hpp>
namespace cv {
namespace ximgproc {
namespace rl {
//! @addtogroup ximgproc_run_length_morphology
//! @{
/**
* @brief Applies a fixed-level threshold to each array element.
*
*
* @param src input array (single-channel).
* @param rlDest resulting run length encoded image.
* @param thresh threshold value.
* @param type thresholding type (only cv::THRESH_BINARY and cv::THRESH_BINARY_INV are supported)
*
*/
CV_EXPORTS void threshold(InputArray src, OutputArray rlDest, double thresh, int type);
/**
* @brief Dilates an run-length encoded binary image by using a specific structuring element.
*
*
* @param rlSrc input image
* @param rlDest result
* @param rlKernel kernel
* @param anchor position of the anchor within the element; default value (0, 0)
* is usually the element center.
*
*/
CV_EXPORTS void dilate(InputArray rlSrc, OutputArray rlDest, InputArray rlKernel, Point anchor = Point(0, 0));
/**
* @brief Erodes an run-length encoded binary image by using a specific structuring element.
*
*
* @param rlSrc input image
* @param rlDest result
* @param rlKernel kernel
* @param bBoundaryOn indicates whether pixel outside the image boundary are assumed to be on
(True: works in the same way as the default of cv::erode, False: is a little faster)
* @param anchor position of the anchor within the element; default value (0, 0)
* is usually the element center.
*
*/
CV_EXPORTS void erode(InputArray rlSrc, OutputArray rlDest, InputArray rlKernel,
bool bBoundaryOn = true, Point anchor = Point(0, 0));
/**
* @brief Returns a run length encoded structuring element of the specified size and shape.
*
*
* @param shape Element shape that can be one of cv::MorphShapes
* @param ksize Size of the structuring element.
*
*/
CV_EXPORTS cv::Mat getStructuringElement(int shape, Size ksize);
/**
* @brief Paint run length encoded binary image into an image.
*
*
* @param image image to paint into (currently only single channel images).
* @param rlSrc run length encoded image
* @param value all foreground pixel of the binary image are set to this value
*
*/
CV_EXPORTS void paint(InputOutputArray image, InputArray rlSrc, const cv::Scalar& value);
/**
* @brief Check whether a custom made structuring element can be used with run length morphological operations.
* (It must consist of a continuous array of single runs per row)
*
* @param rlStructuringElement mask to be tested
*/
CV_EXPORTS bool isRLMorphologyPossible(InputArray rlStructuringElement);
/**
* @brief Creates a run-length encoded image from a vector of runs (column begin, column end, row)
*
* @param runs vector of runs
* @param res result
* @param size image size (to be used if an "on" boundary should be used in erosion, using the default
* means that the size is computed from the extension of the input)
*/
CV_EXPORTS void createRLEImage(const std::vector<cv::Point3i>& runs, OutputArray res, Size size = Size(0, 0));
/**
* @brief Applies a morphological operation to a run-length encoded binary image.
*
*
* @param rlSrc input image
* @param rlDest result
* @param op all operations supported by cv::morphologyEx (except cv::MORPH_HITMISS)
* @param rlKernel kernel
* @param bBoundaryOnForErosion indicates whether pixel outside the image boundary are assumed
* to be on for erosion operations (True: works in the same way as the default of cv::erode,
* False: is a little faster)
* @param anchor position of the anchor within the element; default value (0, 0) is usually the element center.
*
*/
CV_EXPORTS void morphologyEx(InputArray rlSrc, OutputArray rlDest, int op, InputArray rlKernel,
bool bBoundaryOnForErosion = true, Point anchor = Point(0,0));
//! @}
}
}
}
#endif
@@ -0,0 +1,83 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
//
// Copyright (C) 2021, Dr Seng Cheong Loke (lokesengcheong@gmail.com)
#ifndef __OPENCV_XIMGPROC_SCANSEGMENT_HPP__
#define __OPENCV_XIMGPROC_SCANSEGMENT_HPP__
#include <opencv2/core.hpp>
namespace cv { namespace ximgproc {
/** @brief Class implementing the F-DBSCAN (Accelerated superpixel image segmentation with a parallelized DBSCAN algorithm) superpixels
algorithm by Loke SC, et al. @cite loke2021accelerated for original paper.
The algorithm uses a parallelised DBSCAN cluster search that is resistant to noise, competitive in segmentation quality, and faster than
existing superpixel segmentation methods. When tested on the Berkeley Segmentation Dataset, the average processing speed is 175 frames/s
with a Boundary Recall of 0.797 and an Achievable Segmentation Accuracy of 0.944. The computational complexity is quadratic O(n2) and
more suited to smaller images, but can still process a 2MP colour image faster than the SEEDS algorithm in OpenCV. The output is deterministic
when the number of processing threads is fixed, and requires the source image to be in Lab colour format.
*/
class CV_EXPORTS_W ScanSegment : public Algorithm
{
public:
virtual ~ScanSegment();
/** @brief Returns the actual superpixel segmentation from the last image processed using iterate.
Returns zero if no image has been processed.
*/
CV_WRAP virtual int getNumberOfSuperpixels() = 0;
/** @brief Calculates the superpixel segmentation on a given image with the initialized
parameters in the ScanSegment object.
This function can be called again for other images without the need of initializing the algorithm with createScanSegment().
This save the computational cost of allocating memory for all the structures of the algorithm.
@param img Input image. Supported format: CV_8UC3. Image size must match with the initialized
image size with the function createScanSegment(). It MUST be in Lab color space.
*/
CV_WRAP virtual void iterate(InputArray img) = 0;
/** @brief Returns the segmentation labeling of the image.
Each label represents a superpixel, and each pixel is assigned to one superpixel label.
@param labels_out Return: A CV_32UC1 integer array containing the labels of the superpixel
segmentation. The labels are in the range [0, getNumberOfSuperpixels()].
*/
CV_WRAP virtual void getLabels(OutputArray labels_out) = 0;
/** @brief Returns the mask of the superpixel segmentation stored in the ScanSegment object.
The function return the boundaries of the superpixel segmentation.
@param image Return: CV_8UC1 image mask where -1 indicates that the pixel is a superpixel border, and 0 otherwise.
@param thick_line If false, the border is only one pixel wide, otherwise all pixels at the border are masked.
*/
CV_WRAP virtual void getLabelContourMask(OutputArray image, bool thick_line = false) = 0;
};
/** @brief Initializes a ScanSegment object.
The function initializes a ScanSegment object for the input image. It stores the parameters of
the image: image_width and image_height. It also sets the parameters of the F-DBSCAN superpixel
algorithm, which are: num_superpixels, threads, and merge_small.
@param image_width Image width.
@param image_height Image height.
@param num_superpixels Desired number of superpixels. Note that the actual number may be smaller
due to restrictions (depending on the image size). Use getNumberOfSuperpixels() to
get the actual number.
@param slices Number of processing threads for parallelisation. Setting -1 uses the maximum number
of threads. In practice, four threads is enough for smaller images and eight threads for larger ones.
@param merge_small merge small segments to give the desired number of superpixels. Processing is
much faster without merging, but many small segments will be left in the image.
*/
CV_EXPORTS_W cv::Ptr<ScanSegment> createScanSegment(int image_width, int image_height, int num_superpixels, int slices = 8, bool merge_small = true);
}} // namespace
#endif
@@ -0,0 +1,183 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2014, Beat Kueng (beat-kueng@gmx.net), Lukas Vogel, Morten Lysgaard
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#ifndef __OPENCV_SEEDS_HPP__
#define __OPENCV_SEEDS_HPP__
#ifdef __cplusplus
#include <opencv2/core.hpp>
namespace cv
{
namespace ximgproc
{
//! @addtogroup ximgproc_superpixel
//! @{
/** @brief Class implementing the SEEDS (Superpixels Extracted via Energy-Driven Sampling) superpixels
algorithm described in @cite VBRV14 .
The algorithm uses an efficient hill-climbing algorithm to optimize the superpixels' energy
function that is based on color histograms and a boundary term, which is optional. The energy
function encourages superpixels to be of the same color, and if the boundary term is activated, the
superpixels have smooth boundaries and are of similar shape. In practice it starts from a regular
grid of superpixels and moves the pixels or blocks of pixels at the boundaries to refine the
solution. The algorithm runs in real-time using a single CPU.
*/
class CV_EXPORTS_W SuperpixelSEEDS : public Algorithm
{
public:
/** @brief Calculates the superpixel segmentation on a given image stored in SuperpixelSEEDS object.
The function computes the superpixels segmentation of an image with the parameters initialized
with the function createSuperpixelSEEDS().
*/
CV_WRAP virtual int getNumberOfSuperpixels() = 0;
/** @brief Calculates the superpixel segmentation on a given image with the initialized
parameters in the SuperpixelSEEDS object.
This function can be called again for other images without the need of initializing the
algorithm with createSuperpixelSEEDS(). This save the computational cost of allocating memory
for all the structures of the algorithm.
@param img Input image. Supported formats: CV_8U, CV_16U, CV_32F. Image size & number of
channels must match with the initialized image size & channels with the function
createSuperpixelSEEDS(). It should be in HSV or Lab color space. Lab is a bit better, but also
slower.
@param num_iterations Number of pixel level iterations. Higher number improves the result.
The function computes the superpixels segmentation of an image with the parameters initialized
with the function createSuperpixelSEEDS(). The algorithms starts from a grid of superpixels and
then refines the boundaries by proposing updates of blocks of pixels that lie at the boundaries
from large to smaller size, finalizing with proposing pixel updates. An illustrative example
can be seen below.
![image](pics/superpixels_blocks2.png)
*/
CV_WRAP virtual void iterate(InputArray img, int num_iterations=4) = 0;
/** @brief Returns the segmentation labeling of the image.
Each label represents a superpixel, and each pixel is assigned to one superpixel label.
@param labels_out Return: A CV_32UC1 integer array containing the labels of the superpixel
segmentation. The labels are in the range [0, getNumberOfSuperpixels()].
The function returns an image with ssthe labels of the superpixel segmentation. The labels are in
the range [0, getNumberOfSuperpixels()].
*/
CV_WRAP virtual void getLabels(OutputArray labels_out) = 0;
/** @brief Returns the mask of the superpixel segmentation stored in SuperpixelSEEDS object.
@param image Return: CV_8UC1 image mask where -1 indicates that the pixel is a superpixel border,
and 0 otherwise.
@param thick_line If false, the border is only one pixel wide, otherwise all pixels at the border
are masked.
The function return the boundaries of the superpixel segmentation.
@note
- (Python) A demo on how to generate superpixels in images from the webcam can be found at
opencv_source_code/samples/python2/seeds.py
- (cpp) A demo on how to generate superpixels in images from the webcam can be found at
opencv_source_code/modules/ximgproc/samples/seeds.cpp. By adding a file image as a command
line argument, the static image will be used instead of the webcam.
- It will show a window with the video from the webcam with the superpixel boundaries marked
in red (see below). Use Space to switch between different output modes. At the top of the
window there are 4 sliders, from which the user can change on-the-fly the number of
superpixels, the number of block levels, the strength of the boundary prior term to modify
the shape, and the number of iterations at pixel level. This is useful to play with the
parameters and set them to the user convenience. In the console the frame-rate of the
algorithm is indicated.
![image](pics/superpixels_demo.png)
*/
CV_WRAP virtual void getLabelContourMask(OutputArray image, bool thick_line = false) = 0;
virtual ~SuperpixelSEEDS() {}
};
/** @brief Initializes a SuperpixelSEEDS object.
@param image_width Image width.
@param image_height Image height.
@param image_channels Number of channels of the image.
@param num_superpixels Desired number of superpixels. Note that the actual number may be smaller
due to restrictions (depending on the image size and num_levels). Use getNumberOfSuperpixels() to
get the actual number.
@param num_levels Number of block levels. The more levels, the more accurate is the segmentation,
but needs more memory and CPU time.
@param prior enable 3x3 shape smoothing term if \>0. A larger value leads to smoother shapes. prior
must be in the range [0, 5].
@param histogram_bins Number of histogram bins.
@param double_step If true, iterate each block level twice for higher accuracy.
The function initializes a SuperpixelSEEDS object for the input image. It stores the parameters of
the image: image_width, image_height and image_channels. It also sets the parameters of the SEEDS
superpixel algorithm, which are: num_superpixels, num_levels, use_prior, histogram_bins and
double_step.
The number of levels in num_levels defines the amount of block levels that the algorithm use in the
optimization. The initialization is a grid, in which the superpixels are equally distributed through
the width and the height of the image. The larger blocks correspond to the superpixel size, and the
levels with smaller blocks are formed by dividing the larger blocks into 2 x 2 blocks of pixels,
recursively until the smaller block level. An example of initialization of 4 block levels is
illustrated in the following figure.
![image](pics/superpixels_blocks.png)
*/
CV_EXPORTS_W Ptr<SuperpixelSEEDS> createSuperpixelSEEDS(
int image_width, int image_height, int image_channels,
int num_superpixels, int num_levels, int prior = 2,
int histogram_bins=5, bool double_step = false);
//! @}
}
}
#endif
#endif
@@ -0,0 +1,252 @@
/*
By downloading, copying, installing or using the software you agree to this
license. If you do not agree to this license, do not download, install,
copy or use the software.
License Agreement
For Open Source Computer Vision Library
(3-clause BSD License)
Copyright (C) 2013, OpenCV Foundation, all rights reserved.
Third party copyrights are property of their respective owners.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the names of the copyright holders nor the names of the contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
This software is provided by the copyright holders and contributors "as is" and
any express or implied warranties, including, but not limited to, the implied
warranties of merchantability and fitness for a particular purpose are
disclaimed. In no event shall copyright holders or contributors be liable for
any direct, indirect, incidental, special, exemplary, or consequential damages
(including, but not limited to, procurement of substitute goods or services;
loss of use, data, or profits; or business interruption) however caused
and on any theory of liability, whether in contract, strict liability,
or tort (including negligence or otherwise) arising in any way out of
the use of this software, even if advised of the possibility of such damage.
*/
#ifndef __OPENCV_XIMGPROC_SEGMENTATION_HPP__
#define __OPENCV_XIMGPROC_SEGMENTATION_HPP__
#include <opencv2/core.hpp>
namespace cv {
namespace ximgproc {
namespace segmentation {
//! @addtogroup ximgproc_segmentation
//! @{
/** @brief Graph Based Segmentation Algorithm.
The class implements the algorithm described in @cite PFF2004 .
*/
class CV_EXPORTS_W GraphSegmentation : public Algorithm {
public:
/** @brief Segment an image and store output in dst
@param src The input image. Any number of channel (1 (Eg: Gray), 3 (Eg: RGB), 4 (Eg: RGB-D)) can be provided
@param dst The output segmentation. It's a CV_32SC1 Mat with the same number of cols and rows as input image, with an unique, sequential, id for each pixel.
*/
CV_WRAP virtual void processImage(InputArray src, OutputArray dst) = 0;
CV_WRAP virtual void setSigma(double sigma) = 0;
CV_WRAP virtual double getSigma() = 0;
CV_WRAP virtual void setK(float k) = 0;
CV_WRAP virtual float getK() = 0;
CV_WRAP virtual void setMinSize(int min_size) = 0;
CV_WRAP virtual int getMinSize() = 0;
};
/** @brief Creates a graph based segmentor
@param sigma The sigma parameter, used to smooth image
@param k The k parameter of the algorythm
@param min_size The minimum size of segments
*/
CV_EXPORTS_W Ptr<GraphSegmentation> createGraphSegmentation(double sigma=0.5, float k=300, int min_size=100);
/** @brief Strategie for the selective search segmentation algorithm
The class implements a generic stragery for the algorithm described in @cite uijlings2013selective.
*/
class CV_EXPORTS_W SelectiveSearchSegmentationStrategy : public Algorithm {
public:
/** @brief Set a initial image, with a segmentation.
@param img The input image. Any number of channel can be provided
@param regions A segmentation of the image. The parameter must be the same size of img.
@param sizes The sizes of different regions
@param image_id If not set to -1, try to cache pre-computations. If the same set og (img, regions, size) is used, the image_id need to be the same.
*/
CV_WRAP virtual void setImage(InputArray img, InputArray regions, InputArray sizes, int image_id = -1) = 0;
/** @brief Return the score between two regions (between 0 and 1)
@param r1 The first region
@param r2 The second region
*/
CV_WRAP virtual float get(int r1, int r2) = 0;
/** @brief Inform the strategy that two regions will be merged
@param r1 The first region
@param r2 The second region
*/
CV_WRAP virtual void merge(int r1, int r2) = 0;
};
/** @brief Color-based strategy for the selective search segmentation algorithm
The class is implemented from the algorithm described in @cite uijlings2013selective.
*/
class CV_EXPORTS_W SelectiveSearchSegmentationStrategyColor : public SelectiveSearchSegmentationStrategy {
};
/** @brief Create a new color-based strategy */
CV_EXPORTS_W Ptr<SelectiveSearchSegmentationStrategyColor> createSelectiveSearchSegmentationStrategyColor();
/** @brief Size-based strategy for the selective search segmentation algorithm
The class is implemented from the algorithm described in @cite uijlings2013selective.
*/
class CV_EXPORTS_W SelectiveSearchSegmentationStrategySize : public SelectiveSearchSegmentationStrategy {
};
/** @brief Create a new size-based strategy */
CV_EXPORTS_W Ptr<SelectiveSearchSegmentationStrategySize> createSelectiveSearchSegmentationStrategySize();
/** @brief Texture-based strategy for the selective search segmentation algorithm
The class is implemented from the algorithm described in @cite uijlings2013selective.
*/
class CV_EXPORTS_W SelectiveSearchSegmentationStrategyTexture : public SelectiveSearchSegmentationStrategy {
};
/** @brief Create a new size-based strategy */
CV_EXPORTS_W Ptr<SelectiveSearchSegmentationStrategyTexture> createSelectiveSearchSegmentationStrategyTexture();
/** @brief Fill-based strategy for the selective search segmentation algorithm
The class is implemented from the algorithm described in @cite uijlings2013selective.
*/
class CV_EXPORTS_W SelectiveSearchSegmentationStrategyFill : public SelectiveSearchSegmentationStrategy {
};
/** @brief Create a new fill-based strategy */
CV_EXPORTS_W Ptr<SelectiveSearchSegmentationStrategyFill> createSelectiveSearchSegmentationStrategyFill();
/** @brief Regroup multiple strategies for the selective search segmentation algorithm
*/
class CV_EXPORTS_W SelectiveSearchSegmentationStrategyMultiple : public SelectiveSearchSegmentationStrategy {
public:
/** @brief Add a new sub-strategy
@param g The strategy
@param weight The weight of the strategy
*/
CV_WRAP virtual void addStrategy(Ptr<SelectiveSearchSegmentationStrategy> g, float weight) = 0;
/** @brief Remove all sub-strategies
*/
CV_WRAP virtual void clearStrategies() = 0;
};
/** @brief Create a new multiple strategy */
CV_EXPORTS_W Ptr<SelectiveSearchSegmentationStrategyMultiple> createSelectiveSearchSegmentationStrategyMultiple();
/** @brief Create a new multiple strategy and set one subtrategy
@param s1 The first strategy
*/
CV_EXPORTS_W Ptr<SelectiveSearchSegmentationStrategyMultiple> createSelectiveSearchSegmentationStrategyMultiple(Ptr<SelectiveSearchSegmentationStrategy> s1);
/** @brief Create a new multiple strategy and set two subtrategies, with equal weights
@param s1 The first strategy
@param s2 The second strategy
*/
CV_EXPORTS_W Ptr<SelectiveSearchSegmentationStrategyMultiple> createSelectiveSearchSegmentationStrategyMultiple(Ptr<SelectiveSearchSegmentationStrategy> s1, Ptr<SelectiveSearchSegmentationStrategy> s2);
/** @brief Create a new multiple strategy and set three subtrategies, with equal weights
@param s1 The first strategy
@param s2 The second strategy
@param s3 The third strategy
*/
CV_EXPORTS_W Ptr<SelectiveSearchSegmentationStrategyMultiple> createSelectiveSearchSegmentationStrategyMultiple(Ptr<SelectiveSearchSegmentationStrategy> s1, Ptr<SelectiveSearchSegmentationStrategy> s2, Ptr<SelectiveSearchSegmentationStrategy> s3);
/** @brief Create a new multiple strategy and set four subtrategies, with equal weights
@param s1 The first strategy
@param s2 The second strategy
@param s3 The third strategy
@param s4 The forth strategy
*/
CV_EXPORTS_W Ptr<SelectiveSearchSegmentationStrategyMultiple> createSelectiveSearchSegmentationStrategyMultiple(Ptr<SelectiveSearchSegmentationStrategy> s1, Ptr<SelectiveSearchSegmentationStrategy> s2, Ptr<SelectiveSearchSegmentationStrategy> s3, Ptr<SelectiveSearchSegmentationStrategy> s4);
/** @brief Selective search segmentation algorithm
The class implements the algorithm described in @cite uijlings2013selective.
*/
class CV_EXPORTS_W SelectiveSearchSegmentation : public Algorithm {
public:
/** @brief Set a image used by switch* functions to initialize the class
@param img The image
*/
CV_WRAP virtual void setBaseImage(InputArray img) = 0;
/** @brief Initialize the class with the 'Single stragegy' parameters describled in @cite uijlings2013selective.
@param k The k parameter for the graph segmentation
@param sigma The sigma parameter for the graph segmentation
*/
CV_WRAP virtual void switchToSingleStrategy(int k = 200, float sigma = 0.8f) = 0;
/** @brief Initialize the class with the 'Selective search fast' parameters describled in @cite uijlings2013selective.
@param base_k The k parameter for the first graph segmentation
@param inc_k The increment of the k parameter for all graph segmentations
@param sigma The sigma parameter for the graph segmentation
*/
CV_WRAP virtual void switchToSelectiveSearchFast(int base_k = 150, int inc_k = 150, float sigma = 0.8f) = 0;
/** @brief Initialize the class with the 'Selective search fast' parameters describled in @cite uijlings2013selective.
@param base_k The k parameter for the first graph segmentation
@param inc_k The increment of the k parameter for all graph segmentations
@param sigma The sigma parameter for the graph segmentation
*/
CV_WRAP virtual void switchToSelectiveSearchQuality(int base_k = 150, int inc_k = 150, float sigma = 0.8f) = 0;
/** @brief Add a new image in the list of images to process.
@param img The image
*/
CV_WRAP virtual void addImage(InputArray img) = 0;
/** @brief Clear the list of images to process
*/
CV_WRAP virtual void clearImages() = 0;
/** @brief Add a new graph segmentation in the list of graph segementations to process.
@param g The graph segmentation
*/
CV_WRAP virtual void addGraphSegmentation(Ptr<GraphSegmentation> g) = 0;
/** @brief Clear the list of graph segmentations to process;
*/
CV_WRAP virtual void clearGraphSegmentations() = 0;
/** @brief Add a new strategy in the list of strategy to process.
@param s The strategy
*/
CV_WRAP virtual void addStrategy(Ptr<SelectiveSearchSegmentationStrategy> s) = 0;
/** @brief Clear the list of strategy to process;
*/
CV_WRAP virtual void clearStrategies() = 0;
/** @brief Based on all images, graph segmentations and stragies, computes all possible rects and return them
@param rects The list of rects. The first ones are more relevents than the lasts ones.
*/
CV_WRAP virtual void process(CV_OUT std::vector<Rect>& rects) = 0;
};
/** @brief Create a new SelectiveSearchSegmentation class.
*/
CV_EXPORTS_W Ptr<SelectiveSearchSegmentation> createSelectiveSearchSegmentation();
//! @}
}
}
}
#endif
@@ -0,0 +1,168 @@
/*********************************************************************
* Software License Agreement (BSD License)
*
* Copyright (c) 2013
* Radhakrishna Achanta
* email : Radhakrishna [dot] Achanta [at] epfl [dot] ch
* web : http://ivrl.epfl.ch/people/achanta
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*********************************************************************/
/*
"SLIC Superpixels Compared to State-of-the-art Superpixel Methods"
Radhakrishna Achanta, Appu Shaji, Kevin Smith, Aurelien Lucchi, Pascal Fua,
and Sabine Susstrunk, IEEE TPAMI, Volume 34, Issue 11, Pages 2274-2282,
November 2012.
"SLIC Superpixels" Radhakrishna Achanta, Appu Shaji, Kevin Smith,
Aurelien Lucchi, Pascal Fua, and Sabine Süsstrunk, EPFL Technical
Report no. 149300, June 2010.
OpenCV port by: Cristian Balint <cristian dot balint at gmail dot com>
*/
#ifndef __OPENCV_SLIC_HPP__
#define __OPENCV_SLIC_HPP__
#ifdef __cplusplus
#include <opencv2/core.hpp>
namespace cv
{
namespace ximgproc
{
//! @addtogroup ximgproc_superpixel
//! @{
enum SLICType { SLIC = 100, SLICO = 101, MSLIC = 102 };
/** @brief Class implementing the SLIC (Simple Linear Iterative Clustering) superpixels
algorithm described in @cite Achanta2012.
SLIC (Simple Linear Iterative Clustering) clusters pixels using pixel channels and image plane space
to efficiently generate compact, nearly uniform superpixels. The simplicity of approach makes it
extremely easy to use a lone parameter specifies the number of superpixels and the efficiency of
the algorithm makes it very practical.
Several optimizations are available for SLIC class:
SLICO stands for "Zero parameter SLIC" and it is an optimization of baseline SLIC described in @cite Achanta2012.
MSLIC stands for "Manifold SLIC" and it is an optimization of baseline SLIC described in @cite Liu_2017_IEEE.
*/
class CV_EXPORTS_W SuperpixelSLIC : public Algorithm
{
public:
/** @brief Calculates the actual amount of superpixels on a given segmentation computed
and stored in SuperpixelSLIC object.
*/
CV_WRAP virtual int getNumberOfSuperpixels() const = 0;
/** @brief Calculates the superpixel segmentation on a given image with the initialized
parameters in the SuperpixelSLIC object.
This function can be called again without the need of initializing the algorithm with
createSuperpixelSLIC(). This save the computational cost of allocating memory for all the
structures of the algorithm.
@param num_iterations Number of iterations. Higher number improves the result.
The function computes the superpixels segmentation of an image with the parameters initialized
with the function createSuperpixelSLIC(). The algorithms starts from a grid of superpixels and
then refines the boundaries by proposing updates of edges boundaries.
*/
CV_WRAP virtual void iterate( int num_iterations = 10 ) = 0;
/** @brief Returns the segmentation labeling of the image.
Each label represents a superpixel, and each pixel is assigned to one superpixel label.
@param labels_out Return: A CV_32SC1 integer array containing the labels of the superpixel
segmentation. The labels are in the range [0, getNumberOfSuperpixels()].
The function returns an image with the labels of the superpixel segmentation. The labels are in
the range [0, getNumberOfSuperpixels()].
*/
CV_WRAP virtual void getLabels( OutputArray labels_out ) const = 0;
/** @brief Returns the mask of the superpixel segmentation stored in SuperpixelSLIC object.
@param image Return: CV_8U1 image mask where -1 indicates that the pixel is a superpixel border,
and 0 otherwise.
@param thick_line If false, the border is only one pixel wide, otherwise all pixels at the border
are masked.
The function return the boundaries of the superpixel segmentation.
*/
CV_WRAP virtual void getLabelContourMask( OutputArray image, bool thick_line = true ) const = 0;
/** @brief Enforce label connectivity.
@param min_element_size The minimum element size in percents that should be absorbed into a bigger
superpixel. Given resulted average superpixel size valid value should be in 0-100 range, 25 means
that less then a quarter sized superpixel should be absorbed, this is default.
The function merge component that is too small, assigning the previously found adjacent label
to this component. Calling this function may change the final number of superpixels.
*/
CV_WRAP virtual void enforceLabelConnectivity( int min_element_size = 25 ) = 0;
};
/** @brief Initialize a SuperpixelSLIC object
@param image Image to segment
@param algorithm Chooses the algorithm variant to use:
SLIC segments image using a desired region_size, and in addition SLICO will optimize using adaptive compactness factor,
while MSLIC will optimize using manifold methods resulting in more content-sensitive superpixels.
@param region_size Chooses an average superpixel size measured in pixels
@param ruler Chooses the enforcement of superpixel smoothness factor of superpixel
The function initializes a SuperpixelSLIC object for the input image. It sets the parameters of choosed
superpixel algorithm, which are: region_size and ruler. It preallocate some buffers for future
computing iterations over the given image. For enanched results it is recommended for color images to
preprocess image with little gaussian blur using a small 3 x 3 kernel and additional conversion into
CieLAB color space. An example of SLIC versus SLICO and MSLIC is ilustrated in the following picture.
![image](pics/superpixels_slic.png)
*/
CV_EXPORTS_W Ptr<SuperpixelSLIC> createSuperpixelSLIC( InputArray image, int algorithm = SLICO,
int region_size = 10, float ruler = 10.0f );
//! @}
}
}
#endif
#endif
@@ -0,0 +1,270 @@
/*
* By downloading, copying, installing or using the software you agree to this license.
* If you do not agree to this license, do not download, install,
* copy or use the software.
*
*
* License Agreement
* For Open Source Computer Vision Library
* (3 - clause BSD License)
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met :
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and / or other materials provided with the distribution.
*
* * Neither the names of the copyright holders nor the names of the contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* This software is provided by the copyright holders and contributors "as is" and
* any express or implied warranties, including, but not limited to, the implied
* warranties of merchantability and fitness for a particular purpose are disclaimed.
* In no event shall copyright holders or contributors be liable for any direct,
* indirect, incidental, special, exemplary, or consequential damages
* (including, but not limited to, procurement of substitute goods or services;
* loss of use, data, or profits; or business interruption) however caused
* and on any theory of liability, whether in contract, strict liability,
* or tort(including negligence or otherwise) arising in any way out of
* the use of this software, even if advised of the possibility of such damage.
*/
#ifndef __OPENCV_SPARSEMATCHINTERPOLATOR_HPP__
#define __OPENCV_SPARSEMATCHINTERPOLATOR_HPP__
#ifdef __cplusplus
#include <opencv2/core.hpp>
namespace cv {
namespace ximgproc {
//! @addtogroup ximgproc_filters
//! @{
/** @brief Main interface for all filters, that take sparse matches as an
input and produce a dense per-pixel matching (optical flow) as an output.
*/
class CV_EXPORTS_W SparseMatchInterpolator : public Algorithm
{
public:
/** @brief Interpolate input sparse matches.
@param from_image first of the two matched images, 8-bit single-channel or three-channel.
@param from_points points of the from_image for which there are correspondences in the
to_image (Point2f vector or Mat of depth CV_32F)
@param to_image second of the two matched images, 8-bit single-channel or three-channel.
@param to_points points in the to_image corresponding to from_points
(Point2f vector or Mat of depth CV_32F)
@param dense_flow output dense matching (two-channel CV_32F image)
*/
CV_WRAP virtual void interpolate(InputArray from_image, InputArray from_points,
InputArray to_image , InputArray to_points,
OutputArray dense_flow) = 0;
};
/** @brief Sparse match interpolation algorithm based on modified locally-weighted affine
estimator from @cite Revaud2015 and Fast Global Smoother as post-processing filter.
*/
class CV_EXPORTS_W EdgeAwareInterpolator : public SparseMatchInterpolator
{
public:
/** @brief Interface to provide a more elaborated cost map, i.e. edge map, for the edge-aware term.
* This implementation is based on a rather simple gradient-based edge map estimation.
* To used more complex edge map estimator (e.g. StructuredEdgeDetection that has been
* used in the original publication) that may lead to improved accuracies, the internal
* edge map estimation can be bypassed here.
* @param _costMap a type CV_32FC1 Mat is required.
* @see cv::ximgproc::createSuperpixelSLIC
*/
CV_WRAP virtual void setCostMap(const Mat & _costMap) = 0;
/** @brief Parameter to tune the approximate size of the superpixel used for oversegmentation.
* @see cv::ximgproc::createSuperpixelSLIC
*/
/** @brief K is a number of nearest-neighbor matches considered, when fitting a locally affine
model. Usually it should be around 128. However, lower values would make the interpolation
noticeably faster.
*/
CV_WRAP virtual void setK(int _k) = 0;
/** @see setK */
CV_WRAP virtual int getK() = 0;
/** @brief Sigma is a parameter defining how fast the weights decrease in the locally-weighted affine
fitting. Higher values can help preserve fine details, lower values can help to get rid of noise in the
output flow.
*/
CV_WRAP virtual void setSigma(float _sigma) = 0;
/** @see setSigma */
CV_WRAP virtual float getSigma() = 0;
/** @brief Lambda is a parameter defining the weight of the edge-aware term in geodesic distance,
should be in the range of 0 to 1000.
*/
CV_WRAP virtual void setLambda(float _lambda) = 0;
/** @see setLambda */
CV_WRAP virtual float getLambda() = 0;
/** @brief Sets whether the fastGlobalSmootherFilter() post-processing is employed. It is turned on by
default.
*/
CV_WRAP virtual void setUsePostProcessing(bool _use_post_proc) = 0;
/** @see setUsePostProcessing */
CV_WRAP virtual bool getUsePostProcessing() = 0;
/** @brief Sets the respective fastGlobalSmootherFilter() parameter.
*/
CV_WRAP virtual void setFGSLambda(float _lambda) = 0;
/** @see setFGSLambda */
CV_WRAP virtual float getFGSLambda() = 0;
/** @see setFGSLambda */
CV_WRAP virtual void setFGSSigma(float _sigma) = 0;
/** @see setFGSLambda */
CV_WRAP virtual float getFGSSigma() = 0;
};
/** @brief Factory method that creates an instance of the
EdgeAwareInterpolator.
*/
CV_EXPORTS_W
Ptr<EdgeAwareInterpolator> createEdgeAwareInterpolator();
/** @brief Sparse match interpolation algorithm based on modified piecewise locally-weighted affine
* estimator called Robust Interpolation method of Correspondences or RIC from @cite Hu2017 and Variational
* and Fast Global Smoother as post-processing filter. The RICInterpolator is a extension of the EdgeAwareInterpolator.
* Main concept of this extension is an piece-wise affine model based on over-segmentation via SLIC superpixel estimation.
* The method contains an efficient propagation mechanism to estimate among the pieces-wise models.
*/
class CV_EXPORTS_W RICInterpolator : public SparseMatchInterpolator
{
public:
/** @brief K is a number of nearest-neighbor matches considered, when fitting a locally affine
*model for a superpixel segment. However, lower values would make the interpolation
*noticeably faster. The original implementation of @cite Hu2017 uses 32.
*/
CV_WRAP virtual void setK(int k = 32) = 0;
/** @copybrief setK
* @see setK
*/
CV_WRAP virtual int getK() const = 0;
/** @brief Interface to provide a more elaborated cost map, i.e. edge map, for the edge-aware term.
* This implementation is based on a rather simple gradient-based edge map estimation.
* To used more complex edge map estimator (e.g. StructuredEdgeDetection that has been
* used in the original publication) that may lead to improved accuracies, the internal
* edge map estimation can be bypassed here.
* @param costMap a type CV_32FC1 Mat is required.
* @see cv::ximgproc::createSuperpixelSLIC
*/
CV_WRAP virtual void setCostMap(const Mat & costMap) = 0;
/** @brief Get the internal cost, i.e. edge map, used for estimating the edge-aware term.
* @see setCostMap
*/
CV_WRAP virtual void setSuperpixelSize(int spSize = 15) = 0;
/** @copybrief setSuperpixelSize
* @see setSuperpixelSize
*/
CV_WRAP virtual int getSuperpixelSize() const = 0;
/** @brief Parameter defines the number of nearest-neighbor matches for each superpixel considered, when fitting a locally affine
*model.
*/
CV_WRAP virtual void setSuperpixelNNCnt(int spNN = 150) = 0;
/** @copybrief setSuperpixelNNCnt
* @see setSuperpixelNNCnt
*/
CV_WRAP virtual int getSuperpixelNNCnt() const = 0;
/** @brief Parameter to tune enforcement of superpixel smoothness factor used for oversegmentation.
* @see cv::ximgproc::createSuperpixelSLIC
*/
CV_WRAP virtual void setSuperpixelRuler(float ruler = 15.f) = 0;
/** @copybrief setSuperpixelRuler
* @see setSuperpixelRuler
*/
CV_WRAP virtual float getSuperpixelRuler() const = 0;
/** @brief Parameter to choose superpixel algorithm variant to use:
* - cv::ximgproc::SLICType SLIC segments image using a desired region_size (value: 100)
* - cv::ximgproc::SLICType SLICO will optimize using adaptive compactness factor (value: 101)
* - cv::ximgproc::SLICType MSLIC will optimize using manifold methods resulting in more content-sensitive superpixels (value: 102).
* @see cv::ximgproc::createSuperpixelSLIC
*/
CV_WRAP virtual void setSuperpixelMode(int mode = 100) = 0;
/** @copybrief setSuperpixelMode
* @see setSuperpixelMode
*/
CV_WRAP virtual int getSuperpixelMode() const = 0;
/** @brief Alpha is a parameter defining a global weight for transforming geodesic distance into weight.
*/
CV_WRAP virtual void setAlpha(float alpha = 0.7f) = 0;
/** @copybrief setAlpha
* @see setAlpha
*/
CV_WRAP virtual float getAlpha() const = 0;
/** @brief Parameter defining the number of iterations for piece-wise affine model estimation.
*/
CV_WRAP virtual void setModelIter(int modelIter = 4) = 0;
/** @copybrief setModelIter
* @see setModelIter
*/
CV_WRAP virtual int getModelIter() const = 0;
/** @brief Parameter to choose wether additional refinement of the piece-wise affine models is employed.
*/
CV_WRAP virtual void setRefineModels(bool refineModles = true) = 0;
/** @copybrief setRefineModels
* @see setRefineModels
*/
CV_WRAP virtual bool getRefineModels() const = 0;
/** @brief MaxFlow is a threshold to validate the predictions using a certain piece-wise affine model.
* If the prediction exceeds the treshold the translational model will be applied instead.
*/
CV_WRAP virtual void setMaxFlow(float maxFlow = 250.f) = 0;
/** @copybrief setMaxFlow
* @see setMaxFlow
*/
CV_WRAP virtual float getMaxFlow() const = 0;
/** @brief Parameter to choose wether the VariationalRefinement post-processing is employed.
*/
CV_WRAP virtual void setUseVariationalRefinement(bool use_variational_refinement = false) = 0;
/** @copybrief setUseVariationalRefinement
* @see setUseVariationalRefinement
*/
CV_WRAP virtual bool getUseVariationalRefinement() const = 0;
/** @brief Sets whether the fastGlobalSmootherFilter() post-processing is employed.
*/
CV_WRAP virtual void setUseGlobalSmootherFilter(bool use_FGS = true) = 0;
/** @copybrief setUseGlobalSmootherFilter
* @see setUseGlobalSmootherFilter
*/
CV_WRAP virtual bool getUseGlobalSmootherFilter() const = 0;
/** @brief Sets the respective fastGlobalSmootherFilter() parameter.
*/
CV_WRAP virtual void setFGSLambda(float lambda = 500.f) = 0;
/** @copybrief setFGSLambda
* @see setFGSLambda
*/
CV_WRAP virtual float getFGSLambda() const = 0;
/** @brief Sets the respective fastGlobalSmootherFilter() parameter.
*/
CV_WRAP virtual void setFGSSigma(float sigma = 1.5f) = 0;
/** @copybrief setFGSSigma
* @see setFGSSigma
*/
CV_WRAP virtual float getFGSSigma() const = 0;
};
/** @brief Factory method that creates an instance of the
RICInterpolator.
*/
CV_EXPORTS_W
Ptr<RICInterpolator> createRICInterpolator();
//! @}
}
}
#endif
#endif
@@ -0,0 +1,148 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#ifndef __OPENCV_STRUCTURED_EDGE_DETECTION_HPP__
#define __OPENCV_STRUCTURED_EDGE_DETECTION_HPP__
#ifdef __cplusplus
/** @file
@date Jun 17, 2014
@author Yury Gitman
*/
#include <opencv2/core.hpp>
namespace cv
{
namespace ximgproc
{
//! @addtogroup ximgproc_edge
//! @{
/*!
Helper class for training part of [P. Dollar and C. L. Zitnick. Structured Forests for Fast Edge Detection, 2013].
*/
class CV_EXPORTS_W RFFeatureGetter : public Algorithm
{
public:
/*!
* This functions extracts feature channels from src.
* Than StructureEdgeDetection uses this feature space
* to detect edges.
*
* \param src : source image to extract features
* \param features : output n-channel floating point feature matrix.
*
* \param gnrmRad : __rf.options.gradientNormalizationRadius
* \param gsmthRad : __rf.options.gradientSmoothingRadius
* \param shrink : __rf.options.shrinkNumber
* \param outNum : __rf.options.numberOfOutputChannels
* \param gradNum : __rf.options.numberOfGradientOrientations
*/
CV_WRAP virtual void getFeatures(const Mat &src, Mat &features,
const int gnrmRad,
const int gsmthRad,
const int shrink,
const int outNum,
const int gradNum) const = 0;
};
CV_EXPORTS_W Ptr<RFFeatureGetter> createRFFeatureGetter();
/** @brief Class implementing edge detection algorithm from @cite Dollar2013 :
*/
class CV_EXPORTS_W StructuredEdgeDetection : public Algorithm
{
public:
/** @brief The function detects edges in src and draw them to dst.
The algorithm underlies this function is much more robust to texture presence, than common
approaches, e.g. Sobel
@param src source image (RGB, float, in [0;1]) to detect edges
@param dst destination image (grayscale, float, in [0;1]) where edges are drawn
@sa Sobel, Canny
*/
CV_WRAP virtual void detectEdges(cv::InputArray src, cv::OutputArray dst) const = 0;
/** @brief The function computes orientation from edge image.
@param src edge image.
@param dst orientation image.
*/
CV_WRAP virtual void computeOrientation(cv::InputArray src, cv::OutputArray dst) const = 0;
/** @brief The function edgenms in edge image and suppress edges where edge is stronger in orthogonal direction.
@param edge_image edge image from detectEdges function.
@param orientation_image orientation image from computeOrientation function.
@param dst suppressed image (grayscale, float, in [0;1])
@param r radius for NMS suppression.
@param s radius for boundary suppression.
@param m multiplier for conservative suppression.
@param isParallel enables/disables parallel computing.
*/
CV_WRAP virtual void edgesNms(cv::InputArray edge_image, cv::InputArray orientation_image, cv::OutputArray dst, int r = 2, int s = 0, float m = 1, bool isParallel = true) const = 0;
};
/*!
* The only constructor
*
* \param model : name of the file where the model is stored
* \param howToGetFeatures : optional object inheriting from RFFeatureGetter.
* You need it only if you would like to train your
* own forest, pass NULL otherwise
*/
CV_EXPORTS_W Ptr<StructuredEdgeDetection> createStructuredEdgeDetection(const String &model,
Ptr<const RFFeatureGetter> howToGetFeatures = Ptr<RFFeatureGetter>());
//! @}
}
}
#endif
#endif /* __OPENCV_STRUCTURED_EDGE_DETECTION_HPP__ */
@@ -0,0 +1,96 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2015, The Chinese University of Hong Kong, all rights reserved.
//
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#ifndef __OPENCV_WEIGHTED_MEDIAN_FILTER_HPP__
#define __OPENCV_WEIGHTED_MEDIAN_FILTER_HPP__
#ifdef __cplusplus
/**
* @file
* @date Sept 9, 2015
* @author Zhou Chao
*/
#include <opencv2/core.hpp>
#include <string>
namespace cv
{
namespace ximgproc
{
/**
* @brief Specifies weight types of weighted median filter.
*/
enum WMFWeightType
{
WMF_EXP = 1 , //!< \f$exp(-|I1-I2|^2/(2*sigma^2))\f$
WMF_IV1 = 1 << 1, //!< \f$(|I1-I2|+sigma)^-1\f$
WMF_IV2 = 1 << 2, //!< \f$(|I1-I2|^2+sigma^2)^-1\f$
WMF_COS = 1 << 3, //!< \f$dot(I1,I2)/(|I1|*|I2|)\f$
WMF_JAC = 1 << 4, //!< \f$(min(r1,r2)+min(g1,g2)+min(b1,b2))/(max(r1,r2)+max(g1,g2)+max(b1,b2))\f$
WMF_OFF = 1 << 5 //!< unweighted
};
/**
* @brief Applies weighted median filter to an image.
*
* For more details about this implementation, please see @cite zhang2014100+
*
* @param joint Joint 8-bit, 1-channel or 3-channel image.
* @param src Source 8-bit or floating-point, 1-channel or 3-channel image.
* @param dst Destination image.
* @param r Radius of filtering kernel, should be a positive integer.
* @param sigma Filter range standard deviation for the joint image.
* @param weightType weightType The type of weight definition, see WMFWeightType
* @param mask A 0-1 mask that has the same size with I. This mask is used to ignore the effect of some pixels. If the pixel value on mask is 0,
* the pixel will be ignored when maintaining the joint-histogram. This is useful for applications like optical flow occlusion handling.
*
* @sa medianBlur, jointBilateralFilter
*/
CV_EXPORTS_W void weightedMedianFilter(InputArray joint, InputArray src, OutputArray dst,
int r, double sigma = 25.5, int weightType = WMF_EXP, InputArray mask = noArray());
}
}
#endif
#endif
+10
View File
@@ -0,0 +1,10 @@
{
"missing_consts": {
"Ximgproc": {
"public": [
["RO_STRICT", 0],
["RO_IGNORE_BORDERS", 1]
]
}
}
}
@@ -0,0 +1,21 @@
package org.opencv.test.ximgproc;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Point;
import org.opencv.test.OpenCVTestCase;
import org.opencv.ximgproc.Ximgproc;
public class XimgprocTest extends OpenCVTestCase {
public void testHoughPoint2Line() {
Mat src = new Mat(80, 80, CvType.CV_8UC1, new org.opencv.core.Scalar(0));
Point houghPoint = new Point(40, 40);
int[] result = Ximgproc.HoughPoint2Line(houghPoint, src, Ximgproc.ARO_315_135, Ximgproc.HDO_DESKEW, Ximgproc.RO_IGNORE_BORDERS);
assertNotNull(result);
assertEquals(4, result.length);
}
}
+12
View File
@@ -0,0 +1,12 @@
{
"whitelist":
{
"": ["createEdgeDrawing"],
"ximgproc_EdgeDrawing": ["setParams", "detectEdges", "getEdgeImage"],
"ximgproc_EdgeDrawing_Params": ["Params", "PFmode"]
},
"namespace_prefix_override":
{
"ximgproc": ""
}
}
+28
View File
@@ -0,0 +1,28 @@
{
"AdditionalImports" : {
"*" : [ "\"ximgproc.hpp\"" ]
},
"missing_consts" : {
"Ximgproc" : {
"private" : [],
"public" : [
["RO_IGNORE_BORDERS", 1], ["RO_STRICT", 0]
]
}
},
"func_arg_fix" : {
"Ximgproc" : {
"niBlackThreshold" : { "binarizationMethod" : {"ctype" : "LocalBinarizationMethods"} },
"HoughPoint2Line" : { "angleRange" : {"ctype" : "AngleRangeOption"},
"makeSkew" : {"ctype" : "HoughDeskewOption"} },
"weightedMedianFilter" : { "weightType" : {"ctype" : "WMFWeightType"} },
"createDTFilter" : { "mode" : {"ctype" : "EdgeAwareFiltersList"} },
"dtFilter" : { "mode" : {"ctype" : "EdgeAwareFiltersList"} },
"thinning" : { "thinningType" : {"ctype" : "ThinningTypes"} },
"FastHoughTransform" : { "angleRange" : {"ctype" : "AngleRangeOption"},
"makeSkew" : {"ctype" : "HoughDeskewOption"},
"op" : {"ctype" : "HoughOp"} },
"createSuperpixelSLIC" : { "algorithm" : {"ctype" : "SLICType"} }
}
}
}
@@ -0,0 +1,3 @@
#ifdef HAVE_OPENCV_XIMGPROC
typedef cv::ximgproc::EdgeDrawing::Params EdgeDrawing_Params;
#endif
@@ -0,0 +1,24 @@
#!/usr/bin/env python
import cv2 as cv
import numpy as np
from tests_common import NewOpenCVTests
class disparity_test(NewOpenCVTests):
def test_disp(self):
# readGT
ret,GT = cv.ximgproc.readGT(self.find_file("cv/disparityfilter/GT.png"))
self.assertEqual(ret, 0) # returns 0 on success!
self.assertFalse(np.shape(GT) == ())
# computeMSE
left = cv.imread(self.find_file("cv/disparityfilter/disparity_left_raw.png"), cv.IMREAD_UNCHANGED)
self.assertFalse(np.shape(left) == ())
left = np.asarray(left, dtype=np.int16)
mse = cv.ximgproc.computeMSE(GT, left, (0, 0, GT.shape[1], GT.shape[0]))
# computeBadPixelPercent
bad = cv.ximgproc.computeBadPixelPercent(GT, left, (0, 0, GT.shape[1], GT.shape[0]), 24)
if __name__ == '__main__':
NewOpenCVTests.bootstrap()
@@ -0,0 +1,71 @@
#!/usr/bin/env python
import numpy as np
import cv2 as cv
from tests_common import NewOpenCVTests
class Interpolator_test(NewOpenCVTests):
def test_edgeaware_interpolator(self):
# readGT
MAX_DIF = 1.0
MAX_MEAN_DIF = 1.0 / 256.0
src = cv.imread(self.find_file("cv/optflow/RubberWhale1.png"), cv.IMREAD_COLOR)
self.assertFalse(src is None)
ref_flow = cv.readOpticalFlow(self.find_file("cv/sparse_match_interpolator/RubberWhale_reference_result.flo"))
self.assertFalse(ref_flow is None)
matches = np.genfromtxt(self.find_file("cv/sparse_match_interpolator/RubberWhale_sparse_matches.txt")).astype(np.float32)
from_points = matches[:,0:2]
to_points = matches[:,2:4]
interpolator = cv.ximgproc.createEdgeAwareInterpolator()
interpolator.setK(128)
interpolator.setSigma(0.05)
interpolator.setUsePostProcessing(True)
interpolator.setFGSLambda(500.0)
interpolator.setFGSSigma(1.5)
dense_flow = interpolator.interpolate(src, from_points, src, to_points)
self.assertTrue(cv.norm(dense_flow, ref_flow, cv.NORM_INF) <= MAX_DIF)
self.assertTrue(cv.norm(dense_flow, ref_flow, cv.NORM_L1) <= (MAX_MEAN_DIF * dense_flow.shape[0] * dense_flow.shape[1]))
def test_ric_interpolator(self):
# readGT
MAX_DIF = 6.0
MAX_MEAN_DIF = 60.0 / 256.0
src0 = cv.imread(self.find_file("cv/optflow/RubberWhale1.png"), cv.IMREAD_COLOR)
self.assertFalse(src0 is None)
src1 = cv.imread(self.find_file("cv/optflow/RubberWhale2.png"), cv.IMREAD_COLOR)
self.assertFalse(src1 is None)
ref_flow = cv.readOpticalFlow(self.find_file("cv/sparse_match_interpolator/RubberWhale_reference_result.flo"))
self.assertFalse(ref_flow is None)
matches = np.genfromtxt(self.find_file("cv/sparse_match_interpolator/RubberWhale_sparse_matches.txt")).astype(np.float32)
from_points = matches[:,0:2]
to_points = matches[:,2:4]
interpolator = cv.ximgproc.createRICInterpolator()
interpolator.setK(32)
interpolator.setSuperpixelSize(15)
interpolator.setSuperpixelNNCnt(150)
interpolator.setSuperpixelRuler(15.0)
interpolator.setSuperpixelMode(cv.ximgproc.SLIC)
interpolator.setAlpha(0.7)
interpolator.setModelIter(4)
interpolator.setRefineModels(True)
interpolator.setMaxFlow(250)
interpolator.setUseVariationalRefinement(True)
interpolator.setUseGlobalSmootherFilter(True)
interpolator.setFGSLambda(500.0)
interpolator.setFGSSigma(1.5)
dense_flow = interpolator.interpolate(src0, from_points, src1, to_points)
self.assertTrue(cv.norm(dense_flow, ref_flow, cv.NORM_INF) <= MAX_DIF)
self.assertTrue(cv.norm(dense_flow, ref_flow, cv.NORM_L1) <= (MAX_MEAN_DIF * dense_flow.shape[0] * dense_flow.shape[1]))
if __name__ == '__main__':
NewOpenCVTests.bootstrap()
@@ -0,0 +1,49 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "perf_precomp.hpp"
namespace opencv_test { namespace {
typedef tuple<bool, Size, int, int, MatType> AMPerfTestParam;
typedef TestBaseWithParam<AMPerfTestParam> AdaptiveManifoldPerfTest;
PERF_TEST_P( AdaptiveManifoldPerfTest, perf,
Combine(
Values(true, false), //adjust_outliers flag
Values(sz1080p, sz720p), //size
Values(1, 3, 8), //joint channels num
Values(1, 3), //source channels num
Values(CV_8U, CV_32F) //source and joint depth
)
)
{
AMPerfTestParam params = GetParam();
bool adjustOutliers = get<0>(params);
Size sz = get<1>(params);
int jointCnNum = get<2>(params);
int srcCnNum = get<3>(params);
int depth = get<4>(params);
Mat joint(sz, CV_MAKE_TYPE(depth, jointCnNum));
Mat src(sz, CV_MAKE_TYPE(depth, srcCnNum));
Mat dst(sz, CV_MAKE_TYPE(depth, srcCnNum));
declare.in(joint, src, WARMUP_RNG).out(dst);
double sigma_s = 16;
double sigma_r = 0.5;
TEST_CYCLE_N(3)
{
Mat res;
amFilter(joint, src, res, sigma_s, sigma_r, adjustOutliers);
//at 5th cycle sigma_s will be five times more and tree depth will be 5
sigma_s *= 1.38;
sigma_r /= 1.38;
}
SANITY_CHECK_NOTHING();
}
}} // namespace
@@ -0,0 +1,42 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "perf_precomp.hpp"
namespace opencv_test { namespace {
typedef tuple<int, double, double, Size, MatType, int> BTFTestParam;
typedef TestBaseWithParam<BTFTestParam> BilateralTextureFilterTest;
PERF_TEST_P(BilateralTextureFilterTest, perf,
Combine(
Values(2),
Values(0.5),
Values(0.5),
SZ_TYPICAL,
Values(CV_8U, CV_32F),
Values(1, 3))
)
{
BTFTestParam params = GetParam();
int fr = get<0>(params);
double sigmaAlpha = get<1>(params);
double sigmaAvg = get<2>(params);
Size sz = get<3>(params);
int depth = get<4>(params);
int srcCn = get<5>(params);
Mat src(sz, CV_MAKE_TYPE(depth,srcCn));
Mat dst(sz, src.type());
declare.in(src, WARMUP_RNG).out(dst);
TEST_CYCLE_N(1)
{
bilateralTextureFilter(src, dst, fr, 1, sigmaAlpha, sigmaAvg);
}
SANITY_CHECK_NOTHING();
}
}} // namespace
@@ -0,0 +1,128 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "perf_precomp.hpp"
#include "opencv2/ximgproc/disparity_filter.hpp"
namespace opencv_test { namespace {
void MakeArtificialExample(RNG rng, Mat& dst_left_view, Mat& dst_left_disparity_map, Mat& dst_right_disparity_map, Rect& dst_ROI);
CV_ENUM(GuideTypes, CV_8UC3);
CV_ENUM(SrcTypes, CV_16S);
typedef tuple<GuideTypes, SrcTypes, Size, bool, bool> DisparityWLSParams;
typedef TestBaseWithParam<DisparityWLSParams> DisparityWLSFilterPerfTest;
PERF_TEST_P( DisparityWLSFilterPerfTest, perf, Combine(GuideTypes::all(), SrcTypes::all(), Values(sz720p), Values(true,false), Values(true,false)) )
{
RNG rng(0);
DisparityWLSParams params = GetParam();
int guideType = get<0>(params);
int srcType = get<1>(params);
Size sz = get<2>(params);
bool use_conf = get<3>(params);
bool use_downscale = get<4>(params);
Mat guide(sz, guideType);
Mat disp_left(sz, srcType);
Mat disp_right(sz, srcType);
Mat dst(sz, srcType);
Rect ROI;
MakeArtificialExample(rng,guide,disp_left,disp_right,ROI);
if(use_downscale)
{
resize(disp_left,disp_left,Size(),0.5,0.5, INTER_LINEAR_EXACT);
disp_left/=2;
resize(disp_right,disp_right,Size(),0.5,0.5, INTER_LINEAR_EXACT);
disp_right/=2;
ROI = Rect(ROI.x/2,ROI.y/2,ROI.width/2,ROI.height/2);
}
TEST_CYCLE_N(10)
{
Ptr<DisparityWLSFilter> wls_filter = createDisparityWLSFilterGeneric(use_conf);
wls_filter->filter(disp_left,guide,dst,disp_right,ROI);
}
SANITY_CHECK_NOTHING();
}
void MakeArtificialExample(RNG rng, Mat& dst_left_view, Mat& dst_left_disparity_map, Mat& dst_right_disparity_map, Rect& dst_ROI)
{
int w = dst_left_view.cols;
int h = dst_left_view.rows;
//params:
unsigned char bg_level = (unsigned char)rng.uniform(0.0,255.0);
unsigned char fg_level = (unsigned char)rng.uniform(0.0,255.0);
int rect_width = (int)rng.uniform(w/16,w/2);
int rect_height = (int)rng.uniform(h/16,h/2);
int rect_disparity = (int)(0.15*w); //typical maximum disparity value
double sigma = 6.0;
int rect_x_offset = (w-rect_width) /2;
int rect_y_offset = (h-rect_height)/2;
if(dst_left_view.channels()==3)
dst_left_view = Scalar(Vec3b(bg_level,bg_level,bg_level));
else
dst_left_view = Scalar(bg_level);
dst_left_disparity_map = Scalar(0);
dst_right_disparity_map = Scalar(0);
Mat dst_left_view_rect = Mat(dst_left_view, Rect(rect_x_offset,rect_y_offset,rect_width,rect_height));
Mat dst_left_disparity_map_rect = Mat(dst_left_disparity_map,Rect(rect_x_offset,rect_y_offset,rect_width,rect_height));
if(dst_left_view.channels()==3)
dst_left_view_rect = Scalar(Vec3b(fg_level,fg_level,fg_level));
else
dst_left_view_rect = Scalar(fg_level);
dst_left_disparity_map_rect = Scalar(16*rect_disparity);
rect_x_offset-=rect_disparity;
Mat dst_right_disparity_map_rect = Mat(dst_right_disparity_map,Rect(rect_x_offset,rect_y_offset,rect_width,rect_height));
dst_right_disparity_map_rect = Scalar(-16*rect_disparity);
//add some gaussian noise:
unsigned char *l;
short *ldisp, *rdisp;
for(int i=0;i<h;i++)
{
l = dst_left_view.ptr(i);
ldisp = (short*)dst_left_disparity_map.ptr(i);
rdisp = (short*)dst_right_disparity_map.ptr(i);
if(dst_left_view.channels()==3)
{
for(int j=0;j<w;j++)
{
l[0] = saturate_cast<unsigned char>(l[0] + rng.gaussian(sigma));
l[1] = saturate_cast<unsigned char>(l[1] + rng.gaussian(sigma));
l[2] = saturate_cast<unsigned char>(l[2] + rng.gaussian(sigma));
l+=3;
ldisp[0] = saturate_cast<short>(ldisp[0] + rng.gaussian(sigma));
ldisp++;
rdisp[0] = saturate_cast<short>(rdisp[0] + rng.gaussian(sigma));
rdisp++;
}
}
else
{
for(int j=0;j<w;j++)
{
l[0] = saturate_cast<unsigned char>(l[0] + rng.gaussian(sigma));
l++;
ldisp[0] = saturate_cast<short>(ldisp[0] + rng.gaussian(sigma));
ldisp++;
rdisp[0] = saturate_cast<short>(rdisp[0] + rng.gaussian(sigma));
rdisp++;
}
}
}
dst_ROI = Rect(rect_disparity,0,w-rect_disparity,h);
}
}} // namespace
@@ -0,0 +1,46 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "perf_precomp.hpp"
namespace opencv_test { namespace {
CV_ENUM(GuideMatType, CV_8UC1, CV_8UC3, CV_32FC1, CV_32FC3) //reduced set
CV_ENUM(SourceMatType, CV_8UC1, CV_8UC3, CV_8UC4, CV_32FC1, CV_32FC3) //reduced set
CV_ENUM(DTFMode, DTF_NC, DTF_IC, DTF_RF)
typedef tuple<GuideMatType, SourceMatType, Size, double, double, DTFMode> DTTestParams;
typedef TestBaseWithParam<DTTestParams> DomainTransformTest;
PERF_TEST_P( DomainTransformTest, perf,
Combine(
GuideMatType::all(),
SourceMatType::all(),
Values(szVGA, sz720p),
Values(10.0, 80.0),
Values(30.0, 50.0),
DTFMode::all()
)
)
{
int guideType = get<0>(GetParam());
int srcType = get<1>(GetParam());
Size size = get<2>(GetParam());
double sigmaSpatial = get<3>(GetParam());
double sigmaColor = get<4>(GetParam());
int dtfType = get<5>(GetParam());
Mat guide(size, guideType);
Mat src(size, srcType);
Mat dst(size, srcType);
declare.in(guide, src, WARMUP_RNG).out(dst);
TEST_CYCLE_N(5)
{
dtFilter(guide, src, dst, sigmaSpatial, sigmaColor, dtfType);
}
SANITY_CHECK_NOTHING();
}
}} // namespace
@@ -0,0 +1,45 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level
// directory of this distribution and at http://opencv.org/license.html.
//
// Created by Simon Reich
//
#include "perf_precomp.hpp"
namespace opencv_test
{
namespace
{
/* 1. Define parameter type and test fixture */
typedef tuple<int, double> RGFTestParam;
typedef TestBaseWithParam<RGFTestParam> EdgepreservingFilterTest;
/* 2. Declare the testsuite */
PERF_TEST_P(EdgepreservingFilterTest, perf,
Combine(Values(-20, 0, 10), Values(-100, 0, 20)))
{
/* 3. Get actual test parameters */
RGFTestParam params = GetParam();
int kernelSize = get<0>(params);
double threshold = get<1>(params);
/* 4. Allocate and initialize arguments for tested function */
std::string filename = getDataPath("perf/320x260.png");
Mat src = imread(filename, 1);
Mat dst(src.size(), src.type());
/* 5. Manifest your expectations about this test */
declare.in(src).out(dst);
/* 6. Collect the samples! */
PERF_SAMPLE_BEGIN();
ximgproc::edgePreservingFilter(src, dst, kernelSize, threshold);
PERF_SAMPLE_END();
/* 7. Do not check anything */
SANITY_CHECK_NOTHING();
}
} // namespace
} // namespace opencv_test
@@ -0,0 +1,81 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2015, Smart Engines Ltd, all rights reserved.
// Copyright (C) 2015, Institute for Information Transmission Problems of the Russian Academy of Sciences (Kharkevich Institute), all rights reserved.
// Copyright (C) 2015, Dmitry Nikolaev, Simon Karpenko, Michail Aliev, Elena Kuznetsova, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "perf_precomp.hpp"
namespace opencv_test { namespace {
typedef tuple<Size, MatType, MatDepth> srcSize_srcType_dstDepth_t;
typedef perf::TestBaseWithParam<srcSize_srcType_dstDepth_t>
srcSize_srcType_dstDepth;
#define ALL_MAT_DEPHTS CV_8U, CV_8S, CV_16U, CV_32S, CV_32F, CV_64F
PERF_TEST_P(srcSize_srcType_dstDepth, FastHoughTransform,
testing::Combine(
testing::Values(TYPICAL_MAT_SIZES),
testing::Values(TYPICAL_MAT_TYPES),
testing::Values(ALL_MAT_DEPHTS)
)
)
{
Size srcSize = get<0>(GetParam());
int srcType = get<1>(GetParam());
int dstDepth = get<2>(GetParam());
Mat src(srcSize, srcType);
Mat fht;
declare.in(src, WARMUP_RNG);
TEST_CYCLE_N(3)
{
FastHoughTransform(src, fht, dstDepth);
}
SANITY_CHECK_NOTHING();
}
#undef ALL_MAT_DEPHTS
}} // namespace
+39
View File
@@ -0,0 +1,39 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "perf_precomp.hpp"
namespace opencv_test { namespace {
CV_ENUM(GuideTypes, CV_8UC1, CV_8UC3);
CV_ENUM(SrcTypes, CV_8UC1, CV_8UC3, CV_16SC1, CV_16SC3, CV_32FC1, CV_32FC3);
typedef tuple<GuideTypes, SrcTypes, Size> FGSParams;
typedef TestBaseWithParam<FGSParams> FGSFilterPerfTest;
PERF_TEST_P( FGSFilterPerfTest, perf, Combine(GuideTypes::all(), SrcTypes::all(), Values(sz720p)) )
{
RNG rng(0);
FGSParams params = GetParam();
int guideType = get<0>(params);
int srcType = get<1>(params);
Size sz = get<2>(params);
Mat guide(sz, guideType);
Mat src(sz, srcType);
Mat dst(sz, srcType);
declare.in(guide, src, WARMUP_RNG).out(dst);
TEST_CYCLE_N(10)
{
double lambda = rng.uniform(500.0, 10000.0);
double sigma = rng.uniform(1.0, 100.0);
fastGlobalSmootherFilter(guide,src,dst,lambda,sigma);
}
SANITY_CHECK_NOTHING();
}
}} // namespace
@@ -0,0 +1,27 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "perf_precomp.hpp"
namespace opencv_test { namespace {
typedef tuple<Size, MatType, int> FindEllipsesTestParam;
typedef TestBaseWithParam<FindEllipsesTestParam> FindEllipsesTest;
PERF_TEST_P(FindEllipsesTest, perf, Combine(SZ_TYPICAL, Values(CV_8U), Values(1, 3)))
{
FindEllipsesTestParam params = GetParam();
Size sz = get<0>(params);
int matType = get<1>(params);
int srcCn = get<2>(params);
Mat src(sz, CV_MAKE_TYPE(matType, srcCn));
Mat dst(sz, CV_32FC(6));
declare.in(src, WARMUP_RNG).out(dst);
TEST_CYCLE() findEllipses(src, dst, 0.7f, 0.5f, 0.05f);
SANITY_CHECK_NOTHING();
}
}} // namespace
@@ -0,0 +1,40 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "perf_precomp.hpp"
namespace opencv_test { namespace {
CV_ENUM(GuideTypes, CV_8UC1, CV_8UC3, CV_32FC1, CV_32FC3);
CV_ENUM(SrcTypes, CV_8UC1, CV_8UC3, CV_32FC1, CV_32FC3);
typedef tuple<GuideTypes, SrcTypes, Size, double> GFParams;
typedef TestBaseWithParam<GFParams> GuidedFilterPerfTest;
PERF_TEST_P( GuidedFilterPerfTest, perf, Combine(GuideTypes::all(), SrcTypes::all(), Values(sz1080p, sz2K), Values(1./1, 1./2, 1./3, 1./4)) )
{
RNG rng(0);
GFParams params = GetParam();
int guideType = get<0>(params);
int srcType = get<1>(params);
Size sz = get<2>(params);
double scale = get<3>(params);
Mat guide(sz, guideType);
Mat src(sz, srcType);
Mat dst(sz, srcType);
declare.in(guide, src, WARMUP_RNG).out(dst);
TEST_CYCLE_N(3)
{
int radius = rng.uniform(5, 30);
double eps = rng.uniform(0.1, 1e5);
guidedFilter(guide, src, dst, radius, eps, -1, scale);
}
SANITY_CHECK_NOTHING();
}
}} // namespace
@@ -0,0 +1,45 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "perf_precomp.hpp"
namespace opencv_test { namespace {
typedef tuple<double, Size, MatType, int, int> JBFTestParam;
typedef TestBaseWithParam<JBFTestParam> JointBilateralFilterTest;
PERF_TEST_P(JointBilateralFilterTest, perf,
Combine(
Values(4.0, 10.0),
SZ_TYPICAL,
Values(CV_8U, CV_32F),
Values(1, 3),
Values(1, 3))
)
{
JBFTestParam params = GetParam();
double sigmaS = get<0>(params);
Size sz = get<1>(params);
int depth = get<2>(params);
int jCn = get<3>(params);
int srcCn = get<4>(params);
Mat joint(sz, CV_MAKE_TYPE(depth, jCn));
Mat src(sz, CV_MAKE_TYPE(depth, srcCn));
Mat dst(sz, src.type());
declare.in(joint, src, WARMUP_RNG).out(dst);
RNG rnd(cvRound(10*sigmaS) + sz.height + depth + jCn + srcCn);
double sigmaC = rnd.uniform(1.0, 255.0);
TEST_CYCLE_N(1)
{
jointBilateralFilter(joint, src, dst, 0, sigmaC, sigmaS);
}
SANITY_CHECK_NOTHING();
}
}} // namespace
+41
View File
@@ -0,0 +1,41 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "perf_precomp.hpp"
namespace opencv_test { namespace {
typedef tuple<Size, MatType, int> L0SmoothTestParam;
typedef TestBaseWithParam<L0SmoothTestParam> L0SmoothTest;
PERF_TEST_P(L0SmoothTest, perf,
Combine(
SZ_TYPICAL,
Values(CV_8U, CV_16U, CV_32F, CV_64F),
Values(1, 3))
)
{
L0SmoothTestParam params = GetParam();
Size sz = get<0>(params);
int depth = get<1>(params);
int srcCn = get<2>(params);
Mat src(sz, CV_MAKE_TYPE(depth, srcCn));
Mat dst(sz, src.type());
declare.in(src, WARMUP_RNG).out(dst);
RNG rnd(sz.height + depth + srcCn);
double lambda = rnd.uniform(0.01, 0.05);
double kappa = rnd.uniform(1.0, 3.0);
TEST_CYCLE_N(1)
{
l0Smooth(src, dst, lambda, kappa);
}
SANITY_CHECK_NOTHING();
}
}} // namespace
+6
View File
@@ -0,0 +1,6 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "perf_precomp.hpp"
CV_PERF_TEST_MAIN(edgefilter)
+15
View File
@@ -0,0 +1,15 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifndef __OPENCV_PERF_PRECOMP_HPP__
#define __OPENCV_PERF_PRECOMP_HPP__
#include <opencv2/ts.hpp>
#include <opencv2/ximgproc.hpp>
namespace opencv_test {
using namespace perf;
using namespace cv::ximgproc;
}
#endif
@@ -0,0 +1,35 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "perf_precomp.hpp"
namespace opencv_test { namespace {
typedef tuple<Size, MatType> RadonTransformPerfTestParam;
typedef perf::TestBaseWithParam<RadonTransformPerfTestParam> RadonTransformPerfTest;
PERF_TEST_P(RadonTransformPerfTest, perf,
testing::Combine(
testing::Values(TYPICAL_MAT_SIZES),
testing::Values(CV_8UC1, CV_32FC1, CV_64FC1)
)
)
{
Size srcSize = get<0>(GetParam());
int srcType = get<1>(GetParam());
Mat src(srcSize, srcType);
Mat radon;
declare.in(src, WARMUP_RNG);
TEST_CYCLE()
{
RadonTransform(src, radon);
}
SANITY_CHECK_NOTHING();
}
} }
@@ -0,0 +1,34 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "perf_precomp.hpp"
namespace opencv_test { namespace {
typedef tuple<MatDepth, int, Size> RDFParams;
typedef TestBaseWithParam<RDFParams> RidgeDetectionFilterPerfTest;
PERF_TEST_P(RidgeDetectionFilterPerfTest, perf, Combine(
Values((MatDepth)CV_32F),
Values(3),
SZ_TYPICAL
))
{
RDFParams params = GetParam();
int ddepth = get<0>(params);
int ksize = get<1>(params);
Size sz = get<2>(params);
Mat src(sz, ddepth);
Mat out(sz, src.type());
declare.in(src).out(out);
Ptr<RidgeDetectionFilter> rdf = RidgeDetectionFilter::create(ddepth,1, 1, ksize);
TEST_CYCLE() rdf->getRidgeFilteredImage(src, out);
SANITY_CHECK_NOTHING();
}
}} // namespace
@@ -0,0 +1,43 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "perf_precomp.hpp"
namespace opencv_test { namespace {
typedef tuple<double, Size, MatType, int> RGFTestParam;
typedef TestBaseWithParam<RGFTestParam> RollingGuidanceFilterTest;
PERF_TEST_P(RollingGuidanceFilterTest, perf,
Combine(
Values(2.0, 4.0, 6.0, 10.0),
SZ_TYPICAL,
Values(CV_8U, CV_32F),
Values(1, 3))
)
{
RGFTestParam params = GetParam();
double sigmaS = get<0>(params);
Size sz = get<1>(params);
int depth = get<2>(params);
int srcCn = get<3>(params);
Mat src(sz, CV_MAKE_TYPE(depth, srcCn));
Mat dst(sz, src.type());
declare.in(src, WARMUP_RNG).out(dst);
RNG rnd(cvRound(10*sigmaS) + sz.height + depth + srcCn);
double sigmaC = rnd.uniform(1.0, 255.0);
int iterNum = int(rnd.uniform(1.0, 5.0));
TEST_CYCLE_N(1)
{
rollingGuidanceFilter(src, dst, -1, sigmaC, sigmaS, iterNum);
}
SANITY_CHECK_NOTHING();
}
}} // namespace
@@ -0,0 +1,37 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "perf_precomp.hpp"
namespace opencv_test {
namespace {
typedef tuple<int, Size, int> RLParams;
typedef TestBaseWithParam<RLParams> RLMorphologyPerfTest;
PERF_TEST_P(RLMorphologyPerfTest, perf, Combine(Values(1,7, 21), Values(sz720p, sz2160p),
Values(MORPH_ERODE, MORPH_DILATE, MORPH_OPEN, MORPH_CLOSE, MORPH_GRADIENT,MORPH_TOPHAT, MORPH_BLACKHAT)))
{
RLParams params = GetParam();
int seSize = get<0>(params);
Size sz = get<1>(params);
int op = get<2>(params);
Mat src(sz, CV_8U);
Mat thresholded, dstRLE;
Mat se = rl::getStructuringElement(MORPH_ELLIPSE, cv::Size(2 * seSize + 1, 2 * seSize + 1));
declare.in(src, WARMUP_RNG);
TEST_CYCLE_N(4)
{
rl::threshold(src, thresholded, 100.0, THRESH_BINARY);
rl::morphologyEx(thresholded, dstRLE, op, se);
}
SANITY_CHECK_NOTHING();
}
}
} // namespace
+36
View File
@@ -0,0 +1,36 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "perf_precomp.hpp"
namespace opencv_test { namespace {
typedef tuple<Size, int> ThinningPerfParam;
typedef TestBaseWithParam<ThinningPerfParam> ThinningPerfTest;
PERF_TEST_P(ThinningPerfTest, perf,
Combine(
Values(sz1080p, sz720p, szVGA),
Values(THINNING_ZHANGSUEN, THINNING_GUOHALL)
)
)
{
ThinningPerfParam params = GetParam();
Size size = get<0>(params);
int type = get<1>(params);
Mat src = Mat::zeros(size, CV_8UC1);
for (int x = 50; x < src.cols - 50; x += 50)
cv::circle(src, Point(x, x/2), 30 + x/2, Scalar(255), 5);
Mat dst;
TEST_CYCLE()
{
thinning(src, dst, type);
}
SANITY_CHECK_NOTHING();
}
}} // namespace
@@ -0,0 +1,48 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "perf_precomp.hpp"
namespace opencv_test { namespace {
typedef tuple<Size, MatType, int, int, int, WMFWeightType> WMFTestParam;
typedef TestBaseWithParam<WMFTestParam> WeightedMedianFilterTest;
PERF_TEST_P(WeightedMedianFilterTest, perf,
Combine(
Values(szODD, szQVGA),
Values(CV_8U, CV_32F),
Values(1, 3),
Values(1, 3),
Values(3, 5),
Values(WMF_EXP, WMF_COS))
)
{
RNG rnd(1);
WMFTestParam params = GetParam();
double sigma = rnd.uniform(20.0, 30.0);
Size sz = get<0>(params);
int srcDepth = get<1>(params);
int jCn = get<2>(params);
int srcCn = get<3>(params);
int r = get<4>(params);
WMFWeightType weightType = get<5>(params);
Mat joint(sz, CV_MAKE_TYPE(CV_8U, jCn));
Mat src(sz, CV_MAKE_TYPE(srcDepth, srcCn));
Mat dst(sz, src.type());
declare.in(joint, src, WARMUP_RNG).out(dst);
TEST_CYCLE_N(1)
{
weightedMedianFilter(joint, src, dst, r, sigma, weightType);
}
SANITY_CHECK_NOTHING();
}
}} // namespace
+9
View File
@@ -0,0 +1,9 @@
cmake_minimum_required(VERSION 2.8)
project(live_demo)
find_package(OpenCV 3.0 REQUIRED)
set(SOURCES live_demo.cpp)
include_directories(${OpenCV_INCLUDE_DIRS})
add_executable(live_demo ${SOURCES} ${HEADERS})
target_link_libraries(live_demo ${OpenCV_LIBS})
@@ -0,0 +1,106 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2017, IBM Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// @Authors
// Marc Fiammante marc.fiammante@fr.ibm.com
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of OpenCV Foundation or contributors may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the OpenCV Foundation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "opencv2/core/utility.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include <stdio.h>
#include <iostream>
#include "opencv2/ximgproc.hpp"
using namespace cv;
using namespace ximgproc;
using namespace std;
static void help()
{
printf("\nThis sample demonstrates BrightEdge detection\n"
"Call:\n"
" /.edge [image_name -- Default is ../data/ml.png]\n\n");
}
const char* keys =
{
"{help h||}{@image |../data/ml.png|input image name}"
};
int main(int argc, const char** argv)
{
CommandLineParser parser(argc, argv, keys);
if (parser.has("help"))
{
help();
return 0;
}
string filename = parser.get<string>(0);
Mat image = imread(filename, IMREAD_COLOR);
if (image.empty())
{
printf("Cannot read image file: %s\n", filename.c_str());
help();
return -1;
}
// Create a window
// // " original ";
namedWindow("Original");
imshow("Original", image);
// " absdiff ";
Mat edge;
BrightEdges(image, edge, 0); // No contrast
namedWindow("Absolute Difference");
imshow("Absolute Difference", edge);
// " default contrast 1 ";
BrightEdges(image, edge);
namedWindow("Default contrast");
imshow("Default contrast", edge);// Default contrast 1
// " Contrast 5 \n";
BrightEdges(image, edge, 5);
namedWindow("Contrast 5");
imshow("Contrast 5", edge);
// " Contrast 10 \n";
BrightEdges(image, edge, 10);
namedWindow("Contrast 10");
imshow("Contrast 10", edge);
// "wait key ";
waitKey(0);
// "end ";
return 0;
}
@@ -0,0 +1,96 @@
#include <iostream>
#include <fstream>
#include <opencv2/core.hpp>
#include <opencv2/core/utility.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/ximgproc.hpp>
#include <opencv2/ximgproc/color_match.hpp>
using namespace std;
using namespace cv;
static void AddSlider(String sliderName, String windowName, int minSlider, int maxSlider, int valDefault, int *valSlider, void(*f)(int, void *), void *r)
{
createTrackbar(sliderName, windowName, valSlider, 1, f, r);
setTrackbarMin(sliderName, windowName, minSlider);
setTrackbarMax(sliderName, windowName, maxSlider);
setTrackbarPos(sliderName, windowName, valDefault);
}
struct SliderData {
Mat img;
int thresh;
};
static void UpdateThreshImage(int , void *r)
{
SliderData *p = (SliderData*)r;
Mat dst,labels,stats,centroids;
threshold(p->img, dst, p->thresh, 255, THRESH_BINARY);
connectedComponentsWithStats(dst, labels, stats, centroids, 8);
if (centroids.rows < 10)
{
cout << "**********************************************************************************\n";
for (int i = 0; i < centroids.rows; i++)
{
cout << dst.cols - centroids.at<double>(i, 0) << " ";
cout << dst.rows - centroids.at<double>(i, 1) << "\n";
}
cout << "----------------------------------------------------------------------------------\n";
}
flip(dst, dst, -1);
imshow("Max Quaternion corr",dst);
}
int main(int argc, char *argv[])
{
cv::CommandLineParser parser(argc, argv,
"{help h | | match color image }{@colortemplate | | input color template image}{@colorimage | | input color image}");
if (parser.has("help"))
{
parser.printMessage();
return -1;
}
string templateName = parser.get<string>("@colortemplate");
if (templateName.empty())
{
parser.printMessage();
parser.printErrors();
return -2;
}
string colorImageName = parser.get<string>("@colorimage");
if (templateName.empty())
{
parser.printMessage();
parser.printErrors();
return -2;
}
Mat imgLogo = imread(templateName, IMREAD_COLOR);
Mat imgColor = imread(colorImageName, IMREAD_COLOR);
imshow("Image", imgColor);
imshow("template", imgLogo);
// OK NOW WHERE IS OPENCV LOGO ?
Mat imgcorr;
SliderData ps;
ximgproc::colorMatchTemplate(imgColor, imgLogo, imgcorr);
imshow("quaternion correlation real", imgcorr);
normalize(imgcorr, imgcorr,1,0,NORM_MINMAX);
imgcorr.convertTo(ps.img, CV_8U, 255);
imshow("quaternion correlation", imgcorr);
ps.thresh = 0;
AddSlider("Level", "quaternion correlation", 0, 255, ps.thresh, &ps.thresh, UpdateThreshImage, &ps);
int code = 0;
while (code != 27)
{
code = waitKey(50);
}
waitKey(0);
return 0;
}
+417
View File
@@ -0,0 +1,417 @@
#include "opencv2/core.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/core/utility.hpp"
#include <time.h>
#include <vector>
#include <iostream>
#include <opencv2/ximgproc.hpp>
using namespace cv;
#ifdef HAVE_EIGEN
#define MARK_RADIUS 5
#define PALLET_RADIUS 100
int max_width = 1280;
int max_height = 720;
static int globalMouseX;
static int globalMouseY;
static int selected_r;
static int selected_g;
static int selected_b;
static bool globalMouseClick = false;
static bool glb_mouse_left = false;
static bool drawByReference = false;
static bool mouseDraw = false;
static bool mouseClick;
static bool mouseLeft;
static int mouseX;
static int mouseY;
cv::Mat mat_draw;
cv::Mat mat_input_gray;
cv::Mat mat_input_reference;
cv::Mat mat_input_confidence;
cv::Mat mat_pallet(PALLET_RADIUS*2,PALLET_RADIUS*2,CV_8UC3);
static void mouseCallback(int event, int x, int y, int flags, void* param);
void drawTrajectoryByReference(cv::Mat& img);
double module(Point pt);
double distance(Point pt1, Point pt2);
double cross(Point pt1, Point pt2);
double angle(Point pt1, Point pt2);
int inCircle(Point p, Point c, int r);
void createPlate(Mat &im1, int radius);
#endif
const String keys =
"{help h usage ? | | print this message }"
"{@image | | input image }"
"{sigma_spatial |8 | parameter of post-filtering }"
"{sigma_luma |8 | parameter of post-filtering }"
"{sigma_chroma |8 | parameter of post-filtering }"
"{dst_path |None | optional path to save the resulting colorized image }"
"{dst_raw_path |None | optional path to save drawed image before filtering }"
"{draw_by_reference |false | optional flag to use color image as reference }"
;
int main(int argc, char* argv[])
{
CommandLineParser parser(argc,argv,keys);
parser.about("fastBilateralSolverFilter Demo");
if (parser.has("help"))
{
parser.printMessage();
return 0;
}
#ifdef HAVE_EIGEN
String img = parser.get<String>(0);
double sigma_spatial = parser.get<double>("sigma_spatial");
double sigma_luma = parser.get<double>("sigma_luma");
double sigma_chroma = parser.get<double>("sigma_chroma");
String dst_path = parser.get<String>("dst_path");
String dst_raw_path = parser.get<String>("dst_raw_path");
drawByReference = parser.get<bool>("draw_by_reference");
mat_input_reference = cv::imread(img, IMREAD_COLOR);
if (mat_input_reference.empty())
{
std::cerr << "input image '" << img << "' could not be read !" << std::endl << std::endl;
parser.printMessage();
return 1;
}
cvtColor(mat_input_reference, mat_input_gray, COLOR_BGR2GRAY);
if(mat_input_gray.cols > max_width)
{
double scale = float(max_width) / float(mat_input_gray.cols);
cv::resize(mat_input_reference, mat_input_reference, cv::Size(), scale, scale);
cv::resize(mat_input_gray, mat_input_gray, cv::Size(), scale, scale);
}
if(mat_input_gray.rows > max_height)
{
double scale = float(max_height) / float(mat_input_gray.rows);
cv::resize(mat_input_reference, mat_input_reference, cv::Size(), scale, scale);
cv::resize(mat_input_gray, mat_input_gray, cv::Size(), scale, scale);
}
float filtering_time;
std::cout << "mat_input_reference:" << mat_input_reference.cols<<"x"<< mat_input_reference.rows<< std::endl;
std::cout << "please select a color from the palette, by clicking into that," << std::endl;
std::cout << " then select a coarse region in the image to be coloured." << std::endl;
std::cout << " press 'escape' to see the final coloured image." << std::endl;
cv::Mat mat_gray;
cv::cvtColor(mat_input_reference, mat_gray, cv::COLOR_BGR2GRAY);
cv::Mat target = mat_input_reference.clone();
cvtColor(mat_gray, mat_input_reference, COLOR_GRAY2BGR);
cv::namedWindow("draw", cv::WINDOW_AUTOSIZE);
// construct pallet
createPlate(mat_pallet, PALLET_RADIUS);
selected_b = 0;
selected_g = 0;
selected_r = 0;
cv::Mat mat_show(target.rows,target.cols+PALLET_RADIUS*2,CV_8UC3);
cv::Mat color_select(target.rows-mat_pallet.rows,PALLET_RADIUS*2,CV_8UC3,cv::Scalar(selected_b, selected_g, selected_r));
target.copyTo(Mat(mat_show,Rect(0,0,target.cols,target.rows)));
mat_pallet.copyTo(Mat(mat_show,Rect(target.cols,0,mat_pallet.cols,mat_pallet.rows)));
color_select.copyTo(Mat(mat_show,Rect(target.cols,PALLET_RADIUS*2,color_select.cols,color_select.rows)));
cv::imshow("draw", mat_show);
cv::setMouseCallback("draw", mouseCallback, (void *)&mat_show);
mat_input_confidence = 0*cv::Mat::ones(mat_gray.size(),mat_gray.type());
int show_count = 0;
while (1)
{
mouseX = globalMouseX;
mouseY = globalMouseY;
mouseClick = globalMouseClick;
mouseLeft = glb_mouse_left;
if (mouseClick)
{
drawTrajectoryByReference(target);
if(show_count%5==0)
{
cv::Mat target_temp(target.size(),target.type());
filtering_time = static_cast<float>(getTickCount());
if(mouseDraw)
{
cv::cvtColor(target, target_temp, cv::COLOR_BGR2YCrCb);
std::vector<cv::Mat> src_channels;
std::vector<cv::Mat> dst_channels;
cv::split(target_temp,src_channels);
cv::Mat result1 = cv::Mat(mat_input_gray.size(),mat_input_gray.type());
cv::Mat result2 = cv::Mat(mat_input_gray.size(),mat_input_gray.type());
dst_channels.push_back(mat_input_gray);
cv::ximgproc::fastBilateralSolverFilter(mat_input_gray,src_channels[1],mat_input_confidence,result1,sigma_spatial,sigma_luma,sigma_chroma);
dst_channels.push_back(result1);
cv::ximgproc::fastBilateralSolverFilter(mat_input_gray,src_channels[2],mat_input_confidence,result2,sigma_spatial,sigma_luma,sigma_chroma);
dst_channels.push_back(result2);
cv::merge(dst_channels,target_temp);
cv::cvtColor(target_temp, target_temp, cv::COLOR_YCrCb2BGR);
}
else
{
target_temp = target.clone();
}
filtering_time = static_cast<float>(((double)getTickCount() - filtering_time)/getTickFrequency());
std::cout << "solver time: " << filtering_time << "s" << std::endl;
cv::Mat color_selected(target_temp.rows-mat_pallet.rows,PALLET_RADIUS*2,CV_8UC3,cv::Scalar(selected_b, selected_g, selected_r));
target_temp.copyTo(Mat(mat_show,Rect(0,0,target_temp.cols,target_temp.rows)));
mat_pallet.copyTo(Mat(mat_show,Rect(target_temp.cols,0,mat_pallet.cols,mat_pallet.rows)));
color_selected.copyTo(Mat(mat_show,Rect(target_temp.cols,PALLET_RADIUS*2,color_selected.cols,color_selected.rows)));
cv::imshow("draw", mat_show);
}
show_count++;
}
if (cv::waitKey(2) == 27)
break;
}
mat_draw = target.clone();
cv::cvtColor(target, target, cv::COLOR_BGR2YCrCb);
std::vector<cv::Mat> src_channels;
std::vector<cv::Mat> dst_channels;
cv::split(target,src_channels);
cv::Mat result1 = cv::Mat(mat_input_gray.size(),mat_input_gray.type());
cv::Mat result2 = cv::Mat(mat_input_gray.size(),mat_input_gray.type());
filtering_time = static_cast<float>(getTickCount());
// dst_channels.push_back(src_channels[0]);
dst_channels.push_back(mat_input_gray);
cv::ximgproc::fastBilateralSolverFilter(mat_input_gray,src_channels[1],mat_input_confidence,result1,sigma_spatial,sigma_luma,sigma_chroma);
dst_channels.push_back(result1);
cv::ximgproc::fastBilateralSolverFilter(mat_input_gray,src_channels[2],mat_input_confidence,result2,sigma_spatial,sigma_luma,sigma_chroma);
dst_channels.push_back(result2);
cv::merge(dst_channels,target);
cv::cvtColor(target, target, cv::COLOR_YCrCb2BGR);
filtering_time = static_cast<float>(((double)getTickCount() - filtering_time)/getTickFrequency());
std::cout << "solver time: " << filtering_time << "s" << std::endl;
cv::imshow("mat_draw",mat_draw);
cv::imshow("output",target);
if(dst_path!="None")
{
imwrite(dst_path,target);
}
if(dst_raw_path!="None")
{
imwrite(dst_raw_path,mat_draw);
}
cv::waitKey(0);
#else
std::cout << "Can not find eigen, please build with eigen by set WITH_EIGEN=ON" << '\n';
#endif
return 0;
}
#ifdef HAVE_EIGEN
static void mouseCallback(int event, int x, int y, int, void*)
{
switch (event)
{
case cv::EVENT_MOUSEMOVE:
if (globalMouseClick)
{
globalMouseX = x;
globalMouseY = y;
}
break;
case cv::EVENT_LBUTTONDOWN:
globalMouseClick = true;
globalMouseX = x;
globalMouseY = y;
break;
case cv::EVENT_LBUTTONUP:
glb_mouse_left = true;
globalMouseClick = false;
break;
}
}
void drawTrajectoryByReference(cv::Mat& img)
{
int i, j;
uchar red, green, blue;
float gray;
int y, x;
int r = MARK_RADIUS;
int r2 = r * r;
uchar* colorPix;
uchar* grayPix;
if(mouseY < PALLET_RADIUS*2 && img.cols <= mouseX && mouseX < img.cols+PALLET_RADIUS*2)
{
colorPix = mat_pallet.ptr<uchar>(mouseY, mouseX - img.cols);
// colorPix = mat_pallet.ptr<uchar>(mouseY, mouseX);
selected_b = *colorPix;
colorPix++;
selected_g = *colorPix;
colorPix++;
selected_r = *colorPix;
colorPix++;
std::cout << "x y:("<<mouseX<<"," <<mouseY<< " rgb_select:("<< selected_r<<","<<selected_g<<","<<selected_b<<")" << '\n';
}
else
{
mouseDraw = true;
y = mouseY - r;
for(i=-r; i<r+1 ; i++, y++)
{
x = mouseX - r;
colorPix = mat_input_reference.ptr<uchar>(y, x);
grayPix = mat_input_gray.ptr<uchar>(y, x);
for(j=-r; j<r+1; j++, x++)
{
if(i*i + j*j > r2)
{
colorPix += mat_input_reference.channels();
grayPix += mat_input_gray.channels();
continue;
}
if(y<0 || y>=mat_input_reference.rows || x<0 || x>=mat_input_reference.cols)
{
break;
}
blue = *colorPix;
colorPix++;
green = *colorPix;
colorPix++;
red = *colorPix;
colorPix++;
gray = *grayPix;
grayPix++;
mat_input_confidence.at<uchar>(y,x) = 255;
float draw_y = 0.229f*(float(selected_r)) + 0.587f*(float(selected_g)) + 0.114f*(float(selected_b));
int draw_b = int(float(selected_b)*(gray/draw_y));
int draw_g = int(float(selected_g)*(gray/draw_y));
int draw_r = int(float(selected_r)*(gray/draw_y));
if(drawByReference)
{
cv::circle(img, cv::Point2d(x, y), 1, cv::Scalar(blue, green, red), -1);
}
else
{
cv::circle(img, cv::Point2d(x, y), 1, cv::Scalar(draw_b, draw_g, draw_r), -1);
}
}
}
}
}
double module(Point pt)
{
return sqrt((double)pt.x*pt.x + pt.y*pt.y);
}
double distance(Point pt1, Point pt2)
{
int dx = pt1.x - pt2.x;
int dy = pt1.y - pt2.y;
return sqrt((double)dx*dx + dy*dy);
}
double cross(Point pt1, Point pt2)
{
return pt1.x*pt2.x + pt1.y*pt2.y;
}
double angle(Point pt1, Point pt2)
{
return acos(cross(pt1, pt2) / (module(pt1)*module(pt2) + DBL_EPSILON));
}
// p or c is the center
int inCircle(Point p, Point c, int r)
{
int dx = p.x - c.x;
int dy = p.y - c.y;
return dx*dx + dy*dy <= r*r ? 1 : 0;
}
//draw the hsv-plate
void createPlate(Mat &im1, int radius)
{
Mat hsvImag(Size(radius << 1, radius << 1), CV_8UC3, Scalar(0, 0, 255));
int w = hsvImag.cols;
int h = hsvImag.rows;
int cx = w >> 1;
int cy = h >> 1;
Point pt1(cx, 0);
for (int j = 0; j < w; j++)
{
for (int i = 0; i < h; i++)
{
Point pt2(j - cx, i - cy);
if (inCircle(Point(0, 0), pt2, radius))
{
int theta = static_cast<int>(angle(pt1, pt2) * 180 / CV_PI);
if (i > cx)
{
theta = -theta + 360;
}
hsvImag.at<Vec3b>(i, j)[0] = saturate_cast<uchar>(theta / 2);
hsvImag.at<Vec3b>(i, j)[1] = saturate_cast<uchar>(module(pt2) / cx * 255);
hsvImag.at<Vec3b>(i, j)[2] = 255;
}
}
}
cvtColor(hsvImag, im1, COLOR_HSV2BGR);
}
#endif
+59
View File
@@ -0,0 +1,59 @@
import sys
import numpy as np
import cv2 as cv
def AddSlider(sliderName,windowName,minSlider,maxSlider,valDefault, update=[]):
if update is None:
cv.createTrackbar(sliderName, windowName, valDefault,maxSlider-minSlider+1)
else:
cv.createTrackbar(sliderName, windowName, valDefault,maxSlider-minSlider+1, update)
cv.setTrackbarMin(sliderName, windowName, minSlider)
cv.setTrackbarMax(sliderName, windowName, maxSlider)
cv.setTrackbarPos(sliderName, windowName, valDefault)
class Filtrage:
def __init__(self):
self.s =0
self.alpha = 100
self.omega = 100
self.updateFiltre=True
self.img=[]
self.dximg=[]
self.dyimg=[]
self.module=[]
def DericheFilter(self):
self.dximg = cv.ximgproc.GradientDericheX( self.img, self.alpha/100., self.omega/1000. )
self.dyimg = cv.ximgproc.GradientDericheY( self.img, self.alpha/100., self.omega/1000. )
dx2=self.dximg*self.dximg
dy2=self.dyimg*self.dyimg
self.module = np.sqrt(dx2+dy2)
cv.normalize(src=self.module,dst=self.module,norm_type=cv.NORM_MINMAX)
def SlideBarDeriche(self):
cv.namedWindow(self.filename)
AddSlider("alpha",self.filename,1,400,self.alpha,self.UpdateAlpha)
AddSlider("omega",self.filename,1,1000,self.omega,self.UpdateOmega)
def UpdateOmega(self,x ):
self.updateFiltre=True
self.omega=x
def UpdateAlpha(self,x ):
self.updateFiltre=True
self.alpha=x
def run(self,argv):
# Load the source image
self.filename = argv[0] if len(argv) > 0 else "../doc/pics/corridor_fld.jpg"
self.img=cv.imread(self.filename,cv.IMREAD_GRAYSCALE)
if self.img is None:
print ('cannot read file')
return
self.SlideBarDeriche()
while True:
cv.imshow(self.filename,self.img)
if self.updateFiltre:
self.DericheFilter()
cv.imshow("module",self.module)
self.updateFiltre =False
code = cv.waitKey(10)
if code==27:
break
if __name__ == '__main__':
Filtrage().run(sys.argv[1:])
+120
View File
@@ -0,0 +1,120 @@
/*
* By downloading, copying, installing or using the software you agree to this license.
* If you do not agree to this license, do not download, install,
* copy or use the software.
*
*
* License Agreement
* For Open Source Computer Vision Library
* (3 - clause BSD License)
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met :
*
* *Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and / or other materials provided with the distribution.
*
* * Neither the names of the copyright holders nor the names of the contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* This software is provided by the copyright holders and contributors "as is" and
* any express or implied warranties, including, but not limited to, the implied
* warranties of merchantability and fitness for a particular purpose are disclaimed.
* In no event shall copyright holders or contributors be liable for any direct,
* indirect, incidental, special, exemplary, or consequential damages
* (including, but not limited to, procurement of substitute goods or services;
* loss of use, data, or profits; or business interruption) however caused
* and on any theory of liability, whether in contract, strict liability,
* or tort(including negligence or otherwise) arising in any way out of
* the use of this software, even if advised of the possibility of such damage.
*/
#include <opencv2/core.hpp>
#include <opencv2/core/utility.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/ximgproc.hpp>
#include "opencv2/ximgproc/deriche_filter.hpp"
using namespace cv;
using namespace cv::ximgproc;
#include <iostream>
using namespace std;
int alDerive=100;
int alMean=100;
Ptr<Mat> img;
const string & winName = "Gradient Modulus";
static void DisplayImage(Mat x,string s)
{
vector<Mat> sx;
split(x, sx);
vector<double> minVal(3), maxVal(3);
for (size_t i = 0; i < sx.size(); i++)
{
minMaxLoc(sx[i], &minVal[i], &maxVal[i]);
}
maxVal[0] = *max_element(maxVal.begin(), maxVal.end());
minVal[0] = *min_element(minVal.begin(), minVal.end());
Mat uc;
x.convertTo(uc, CV_8U,255/(maxVal[0]-minVal[0]),-255*minVal[0]/(maxVal[0]-minVal[0]));
imshow(s, uc);
}
/**
* @function DericheFilter
* @brief Trackbar callback
*/
static void DericheFilter(int, void*)
{
Mat dst;
double d=alDerive/100.0,m=alMean/100.0;
Mat rx,ry;
GradientDericheX(*img.get(),rx,d,m);
GradientDericheY(*img.get(),ry,d,m);
DisplayImage(rx, "Gx");
DisplayImage(ry, "Gy");
add(rx.mul(rx),ry.mul(ry),dst);
sqrt(dst,dst);
DisplayImage(dst, winName );
}
int main(int argc, char* argv[])
{
Mat *m=new Mat;
cv::CommandLineParser parser(argc, argv, "{help h | | show help message}{@input | | input image}");
if (parser.has("help"))
{
parser.printMessage();
return -1;
}
string input_image = parser.get<string>("@input");
if (input_image.empty())
{
parser.printMessage();
parser.printErrors();
return -2;
}
if (argc==2)
*m = imread(input_image);
if (m->empty())
{
cout << "File not found or empty image\n";
return -3;
}
imshow("Original", *m);
img =Ptr<Mat>(m);
namedWindow( winName, WINDOW_AUTOSIZE );
/// Create a Trackbar for user to enter threshold
createTrackbar( "Derive:",winName, &alDerive, 400, DericheFilter );
createTrackbar( "Mean:", winName, &alMean, 400, DericheFilter );
DericheFilter(0,NULL);
waitKey();
return 0;
}
@@ -0,0 +1,477 @@
#include "opencv2/stereo.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/core/utility.hpp"
#include "opencv2/ximgproc.hpp"
#include <iostream>
#include <string>
using namespace cv;
using namespace cv::ximgproc;
using namespace std;
Rect computeROI(Size2i src_sz, Ptr<StereoMatcher> matcher_instance);
const String keys =
"{help h usage ? | | print this message }"
"{@left |../data/aloeL.jpg | left view of the stereopair }"
"{@right |../data/aloeR.jpg | right view of the stereopair }"
"{GT |../data/aloeGT.png| optional ground-truth disparity (MPI-Sintel or Middlebury format) }"
"{dst_path |None | optional path to save the resulting filtered disparity map }"
"{dst_raw_path |None | optional path to save raw disparity map before filtering }"
"{algorithm |bm | stereo matching method (bm or sgbm) }"
"{filter |wls_conf | used post-filtering (wls_conf or wls_no_conf or fbs_conf) }"
"{no-display | | don't display results }"
"{no-downscale | | force stereo matching on full-sized views to improve quality }"
"{dst_conf_path |None | optional path to save the confidence map used in filtering }"
"{vis_mult |1.0 | coefficient used to scale disparity map visualizations }"
"{max_disparity |160 | parameter of stereo matching }"
"{window_size |-1 | parameter of stereo matching }"
"{wls_lambda |8000.0 | parameter of wls post-filtering }"
"{wls_sigma |1.5 | parameter of wls post-filtering }"
"{fbs_spatial |16.0 | parameter of fbs post-filtering }"
"{fbs_luma |8.0 | parameter of fbs post-filtering }"
"{fbs_chroma |8.0 | parameter of fbs post-filtering }"
"{fbs_lambda |128.0 | parameter of fbs post-filtering }"
;
int main(int argc, char** argv)
{
CommandLineParser parser(argc,argv,keys);
parser.about("Disparity Filtering Demo");
if (parser.has("help"))
{
parser.printMessage();
return 0;
}
String left_im = parser.get<String>(0);
String right_im = parser.get<String>(1);
String GT_path = parser.get<String>("GT");
String dst_path = parser.get<String>("dst_path");
String dst_raw_path = parser.get<String>("dst_raw_path");
String dst_conf_path = parser.get<String>("dst_conf_path");
String algo = parser.get<String>("algorithm");
String filter = parser.get<String>("filter");
bool no_display = parser.has("no-display");
bool no_downscale = parser.has("no-downscale");
int max_disp = parser.get<int>("max_disparity");
double lambda = parser.get<double>("wls_lambda");
double sigma = parser.get<double>("wls_sigma");
double fbs_spatial = parser.get<double>("fbs_spatial");
double fbs_luma = parser.get<double>("fbs_luma");
double fbs_chroma = parser.get<double>("fbs_chroma");
double fbs_lambda = parser.get<double>("fbs_lambda");
double vis_mult = parser.get<double>("vis_mult");
int wsize;
if(parser.get<int>("window_size")>=0) //user provided window_size value
wsize = parser.get<int>("window_size");
else
{
if(algo=="sgbm")
wsize = 3; //default window size for SGBM
else if(!no_downscale && algo=="bm" && filter=="wls_conf")
wsize = 7; //default window size for BM on downscaled views (downscaling is performed only for wls_conf)
else
wsize = 15; //default window size for BM on full-sized views
}
if (!parser.check())
{
parser.printErrors();
return -1;
}
//! [load_views]
Mat left = imread(left_im ,IMREAD_COLOR);
if ( left.empty() )
{
cout<<"Cannot read image file: "<<left_im;
return -1;
}
Mat right = imread(right_im,IMREAD_COLOR);
if ( right.empty() )
{
cout<<"Cannot read image file: "<<right_im;
return -1;
}
//! [load_views]
bool noGT;
Mat GT_disp;
if (GT_path=="../data/aloeGT.png" && left_im!="../data/aloeL.jpg")
noGT=true;
else
{
noGT=false;
if(readGT(GT_path,GT_disp)!=0)
{
cout<<"Cannot read ground truth image file: "<<GT_path<<endl;
return -1;
}
}
Mat left_for_matcher, right_for_matcher;
Mat left_disp,right_disp;
Mat filtered_disp,solved_disp,solved_filtered_disp;
Mat conf_map = Mat(left.rows,left.cols,CV_8U);
conf_map = Scalar(255);
Rect ROI;
Ptr<DisparityWLSFilter> wls_filter;
double matching_time, filtering_time;
double solving_time = 0;
if(max_disp<=0 || max_disp%16!=0)
{
cout<<"Incorrect max_disparity value: it should be positive and divisible by 16";
return -1;
}
if(wsize<=0 || wsize%2!=1)
{
cout<<"Incorrect window_size value: it should be positive and odd";
return -1;
}
if(filter=="wls_conf") // filtering with confidence (significantly better quality than wls_no_conf)
{
if(!no_downscale)
{
// downscale the views to speed-up the matching stage, as we will need to compute both left
// and right disparity maps for confidence map computation
//! [downscale]
max_disp/=2;
if(max_disp%16!=0)
max_disp += 16-(max_disp%16);
resize(left ,left_for_matcher ,Size(),0.5,0.5, INTER_LINEAR_EXACT);
resize(right,right_for_matcher,Size(),0.5,0.5, INTER_LINEAR_EXACT);
//! [downscale]
}
else
{
left_for_matcher = left.clone();
right_for_matcher = right.clone();
}
if(algo=="bm")
{
//! [matching]
Ptr<StereoBM> left_matcher = StereoBM::create(max_disp,wsize);
wls_filter = createDisparityWLSFilter(left_matcher);
Ptr<StereoMatcher> right_matcher = createRightMatcher(left_matcher);
cvtColor(left_for_matcher, left_for_matcher, COLOR_BGR2GRAY);
cvtColor(right_for_matcher, right_for_matcher, COLOR_BGR2GRAY);
matching_time = (double)getTickCount();
left_matcher-> compute(left_for_matcher, right_for_matcher,left_disp);
right_matcher->compute(right_for_matcher,left_for_matcher, right_disp);
matching_time = ((double)getTickCount() - matching_time)/getTickFrequency();
//! [matching]
}
else if(algo=="sgbm")
{
Ptr<StereoSGBM> left_matcher = StereoSGBM::create(0,max_disp,wsize);
left_matcher->setP1(24*wsize*wsize);
left_matcher->setP2(96*wsize*wsize);
left_matcher->setPreFilterCap(63);
left_matcher->setMode(StereoSGBM::MODE_SGBM_3WAY);
wls_filter = createDisparityWLSFilter(left_matcher);
Ptr<StereoMatcher> right_matcher = createRightMatcher(left_matcher);
matching_time = (double)getTickCount();
left_matcher-> compute(left_for_matcher, right_for_matcher,left_disp);
right_matcher->compute(right_for_matcher,left_for_matcher, right_disp);
matching_time = ((double)getTickCount() - matching_time)/getTickFrequency();
}
else
{
cout<<"Unsupported algorithm";
return -1;
}
//! [filtering]
wls_filter->setLambda(lambda);
wls_filter->setSigmaColor(sigma);
filtering_time = (double)getTickCount();
wls_filter->filter(left_disp,left,filtered_disp,right_disp);
filtering_time = ((double)getTickCount() - filtering_time)/getTickFrequency();
//! [filtering]
conf_map = wls_filter->getConfidenceMap();
// Get the ROI that was used in the last filter call:
ROI = wls_filter->getROI();
if(!no_downscale)
{
// upscale raw disparity and ROI back for a proper comparison:
resize(left_disp,left_disp,Size(),2.0,2.0,INTER_LINEAR_EXACT);
left_disp = left_disp*2.0;
ROI = Rect(ROI.x*2,ROI.y*2,ROI.width*2,ROI.height*2);
}
}
else if(filter=="fbs_conf") // filtering with fbs and confidence using also wls pre-processing
{
if(!no_downscale)
{
// downscale the views to speed-up the matching stage, as we will need to compute both left
// and right disparity maps for confidence map computation
//! [downscale_wls]
max_disp/=2;
if(max_disp%16!=0)
max_disp += 16-(max_disp%16);
resize(left ,left_for_matcher ,Size(),0.5,0.5);
resize(right,right_for_matcher,Size(),0.5,0.5);
//! [downscale_wls]
}
else
{
left_for_matcher = left.clone();
right_for_matcher = right.clone();
}
if(algo=="bm")
{
//! [matching_wls]
Ptr<StereoBM> left_matcher = StereoBM::create(max_disp,wsize);
wls_filter = createDisparityWLSFilter(left_matcher);
Ptr<StereoMatcher> right_matcher = createRightMatcher(left_matcher);
cvtColor(left_for_matcher, left_for_matcher, COLOR_BGR2GRAY);
cvtColor(right_for_matcher, right_for_matcher, COLOR_BGR2GRAY);
matching_time = (double)getTickCount();
left_matcher-> compute(left_for_matcher, right_for_matcher,left_disp);
right_matcher->compute(right_for_matcher,left_for_matcher, right_disp);
matching_time = ((double)getTickCount() - matching_time)/getTickFrequency();
//! [matching_wls]
}
else if(algo=="sgbm")
{
Ptr<StereoSGBM> left_matcher = StereoSGBM::create(0,max_disp,wsize);
left_matcher->setP1(24*wsize*wsize);
left_matcher->setP2(96*wsize*wsize);
left_matcher->setPreFilterCap(63);
left_matcher->setMode(StereoSGBM::MODE_SGBM_3WAY);
wls_filter = createDisparityWLSFilter(left_matcher);
Ptr<StereoMatcher> right_matcher = createRightMatcher(left_matcher);
matching_time = (double)getTickCount();
left_matcher-> compute(left_for_matcher, right_for_matcher,left_disp);
right_matcher->compute(right_for_matcher,left_for_matcher, right_disp);
matching_time = ((double)getTickCount() - matching_time)/getTickFrequency();
}
else
{
cout<<"Unsupported algorithm";
return -1;
}
//! [filtering_wls]
wls_filter->setLambda(lambda);
wls_filter->setSigmaColor(sigma);
filtering_time = (double)getTickCount();
wls_filter->filter(left_disp,left,filtered_disp,right_disp);
filtering_time = ((double)getTickCount() - filtering_time)/getTickFrequency();
//! [filtering_wls]
conf_map = wls_filter->getConfidenceMap();
Mat left_disp_resized;
resize(left_disp,left_disp_resized,left.size());
// Get the ROI that was used in the last filter call:
ROI = wls_filter->getROI();
if(!no_downscale)
{
// upscale raw disparity and ROI back for a proper comparison:
resize(left_disp,left_disp,Size(),2.0,2.0);
left_disp = left_disp*2.0;
left_disp_resized = left_disp_resized*2.0;
ROI = Rect(ROI.x*2,ROI.y*2,ROI.width*2,ROI.height*2);
}
#ifdef HAVE_EIGEN
//! [filtering_fbs]
solving_time = (double)getTickCount();
fastBilateralSolverFilter(left, left_disp_resized, conf_map/255.0f, solved_disp, fbs_spatial, fbs_luma, fbs_chroma, fbs_lambda);
solving_time = ((double)getTickCount() - solving_time)/getTickFrequency();
//! [filtering_fbs]
//! [filtering_wls2fbs]
fastBilateralSolverFilter(left, filtered_disp, conf_map/255.0f, solved_filtered_disp, fbs_spatial, fbs_luma, fbs_chroma, fbs_lambda);
//! [filtering_wls2fbs]
#else
(void)fbs_spatial;
(void)fbs_luma;
(void)fbs_chroma;
(void)fbs_lambda;
#endif
}
else if(filter=="wls_no_conf")
{
/* There is no convenience function for the case of filtering with no confidence, so we
will need to set the ROI and matcher parameters manually */
left_for_matcher = left.clone();
right_for_matcher = right.clone();
if(algo=="bm")
{
Ptr<StereoBM> matcher = StereoBM::create(max_disp,wsize);
matcher->setTextureThreshold(0);
matcher->setUniquenessRatio(0);
cvtColor(left_for_matcher, left_for_matcher, COLOR_BGR2GRAY);
cvtColor(right_for_matcher, right_for_matcher, COLOR_BGR2GRAY);
ROI = computeROI(left_for_matcher.size(),matcher);
wls_filter = createDisparityWLSFilterGeneric(false);
wls_filter->setDepthDiscontinuityRadius((int)ceil(0.33*wsize));
matching_time = (double)getTickCount();
matcher->compute(left_for_matcher,right_for_matcher,left_disp);
matching_time = ((double)getTickCount() - matching_time)/getTickFrequency();
}
else if(algo=="sgbm")
{
Ptr<StereoSGBM> matcher = StereoSGBM::create(0,max_disp,wsize);
matcher->setUniquenessRatio(0);
matcher->setDisp12MaxDiff(1000000);
matcher->setSpeckleWindowSize(0);
matcher->setP1(24*wsize*wsize);
matcher->setP2(96*wsize*wsize);
matcher->setMode(StereoSGBM::MODE_SGBM_3WAY);
ROI = computeROI(left_for_matcher.size(),matcher);
wls_filter = createDisparityWLSFilterGeneric(false);
wls_filter->setDepthDiscontinuityRadius((int)ceil(0.5*wsize));
matching_time = (double)getTickCount();
matcher->compute(left_for_matcher,right_for_matcher,left_disp);
matching_time = ((double)getTickCount() - matching_time)/getTickFrequency();
}
else
{
cout<<"Unsupported algorithm";
return -1;
}
wls_filter->setLambda(lambda);
wls_filter->setSigmaColor(sigma);
filtering_time = (double)getTickCount();
wls_filter->filter(left_disp,left,filtered_disp,Mat(),ROI);
filtering_time = ((double)getTickCount() - filtering_time)/getTickFrequency();
}
else
{
cout<<"Unsupported filter";
return -1;
}
//collect and print all the stats:
cout.precision(2);
cout<<"Matching time: "<<matching_time<<"s"<<endl;
cout<<"Filtering time: "<<filtering_time<<"s"<<endl;
cout<<"Solving time: "<<solving_time<<"s"<<endl;
cout<<endl;
double MSE_before,percent_bad_before,MSE_after,percent_bad_after;
if(!noGT)
{
MSE_before = computeMSE(GT_disp,left_disp,ROI);
percent_bad_before = computeBadPixelPercent(GT_disp,left_disp,ROI);
MSE_after = computeMSE(GT_disp,filtered_disp,ROI);
percent_bad_after = computeBadPixelPercent(GT_disp,filtered_disp,ROI);
cout.precision(5);
cout<<"MSE before filtering: "<<MSE_before<<endl;
cout<<"MSE after filtering: "<<MSE_after<<endl;
cout<<endl;
cout.precision(3);
cout<<"Percent of bad pixels before filtering: "<<percent_bad_before<<endl;
cout<<"Percent of bad pixels after filtering: "<<percent_bad_after<<endl;
}
if(dst_path!="None")
{
Mat filtered_disp_vis;
getDisparityVis(filtered_disp,filtered_disp_vis,vis_mult);
imwrite(dst_path,filtered_disp_vis);
}
if(dst_raw_path!="None")
{
Mat raw_disp_vis;
getDisparityVis(left_disp,raw_disp_vis,vis_mult);
imwrite(dst_raw_path,raw_disp_vis);
}
if(dst_conf_path!="None")
{
imwrite(dst_conf_path,conf_map);
}
if(!no_display)
{
namedWindow("left", WINDOW_AUTOSIZE);
imshow("left", left);
namedWindow("right", WINDOW_AUTOSIZE);
imshow("right", right);
if(!noGT)
{
Mat GT_disp_vis;
getDisparityVis(GT_disp,GT_disp_vis,vis_mult);
namedWindow("ground-truth disparity", WINDOW_AUTOSIZE);
imshow("ground-truth disparity", GT_disp_vis);
}
//! [visualization]
Mat raw_disp_vis;
getDisparityVis(left_disp,raw_disp_vis,vis_mult);
namedWindow("raw disparity", WINDOW_AUTOSIZE);
imshow("raw disparity", raw_disp_vis);
Mat filtered_disp_vis;
getDisparityVis(filtered_disp,filtered_disp_vis,vis_mult);
namedWindow("filtered disparity", WINDOW_AUTOSIZE);
imshow("filtered disparity", filtered_disp_vis);
if(!solved_disp.empty())
{
Mat solved_disp_vis;
getDisparityVis(solved_disp,solved_disp_vis,vis_mult);
namedWindow("solved disparity", WINDOW_AUTOSIZE);
imshow("solved disparity", solved_disp_vis);
Mat solved_filtered_disp_vis;
getDisparityVis(solved_filtered_disp,solved_filtered_disp_vis,vis_mult);
namedWindow("solved wls disparity", WINDOW_AUTOSIZE);
imshow("solved wls disparity", solved_filtered_disp_vis);
}
while(1)
{
char key = (char)waitKey();
if( key == 27 || key == 'q' || key == 'Q') // 'ESC'
break;
}
//! [visualization]
}
return 0;
}
Rect computeROI(Size2i src_sz, Ptr<StereoMatcher> matcher_instance)
{
int min_disparity = matcher_instance->getMinDisparity();
int num_disparities = matcher_instance->getNumDisparities();
int block_size = matcher_instance->getBlockSize();
int bs2 = block_size/2;
int minD = min_disparity, maxD = min_disparity + num_disparities - 1;
int xmin = maxD + bs2;
int xmax = src_sz.width + minD - bs2;
int ymin = bs2;
int ymax = src_sz.height - bs2;
Rect r(xmin, ymin, xmax - xmin, ymax - ymin);
return r;
}
+151
View File
@@ -0,0 +1,151 @@
#!/usr/bin/python
'''
This example script illustrates how to use cv.ximgproc.EdgeDrawing class.
It uses the OpenCV library to load an image, and then use the EdgeDrawing class
to detect edges, lines, and ellipses. The detected features are then drawn and displayed.
The main loop allows the user changing parameters of EdgeDrawing by pressing following keys:
to toggle the grayscale conversion press 'space' key
to increase MinPathLength value press '/' key
to decrease MinPathLength value press '*' key
to increase MinLineLength value press '+' key
to decrease MinLineLength value press '-' key
to toggle NFAValidation value press 'n' key
to toggle PFmode value press 'p' key
to save parameters to file press 's' key
to load parameters from file press 'l' key
The program exits when the Esc key is pressed.
Usage:
ed.py [<image_name>]
image argument defaults to board.jpg
'''
# Python 2/3 compatibility
from __future__ import print_function
import numpy as np
import cv2 as cv
import random as rng
import sys
def EdgeDrawingDemo(src, ed, EDParams, convert_to_gray):
rng.seed(12345)
ssrc = np.zeros_like(src)
lsrc = src.copy()
esrc = src.copy()
img_to_detect = cv.cvtColor(src, cv.COLOR_BGR2GRAY) if convert_to_gray else src
cv.imshow("source image", img_to_detect)
print("")
print("convert_to_gray:", convert_to_gray)
print("MinPathLength:", EDParams.MinPathLength)
print("MinLineLength:", EDParams.MinLineLength)
print("PFmode:", EDParams.PFmode)
print("NFAValidation:", EDParams.NFAValidation)
tm = cv.TickMeter()
tm.start()
# Detect edges
# you should call this before detectLines() and detectEllipses()
ed.detectEdges(img_to_detect)
segments = ed.getSegments()
lines = ed.detectLines()
ellipses = ed.detectEllipses()
tm.stop()
print("Detection time : {:.2f} ms. using the parameters above".format(tm.getTimeMilli()))
# Draw detected edge segments
for segment in segments:
color = (rng.randint(0, 256), rng.randint(0, 256), rng.randint(0, 256))
cv.polylines(ssrc, [segment], False, color, 1, cv.LINE_8)
cv.imshow("detected edge segments", ssrc)
# Draw detected lines
if lines is not None: # Check if the lines have been found and only then iterate over these and add them to the image
lines = np.uint16(np.around(lines))
for line in lines:
cv.line(lsrc, (line[0][0], line[0][1]), (line[0][2], line[0][3]), (0, 0, 255), 1, cv.LINE_AA)
cv.imshow("detected lines", lsrc)
# Draw detected circles and ellipses
if ellipses is not None: # Check if circles and ellipses have been found and only then iterate over these and add them to the image
for ellipse in ellipses:
center = (int(ellipse[0][0]), int(ellipse[0][1]))
axes = (int(ellipse[0][2] + ellipse[0][3]), int(ellipse[0][2] + ellipse[0][4]))
angle = ellipse[0][5]
color = (0, 255, 0) if ellipse[0][2] == 0 else (0, 0, 255)
cv.ellipse(esrc, center, axes, angle, 0, 360, color, 2, cv.LINE_AA)
cv.imshow("detected circles and ellipses", esrc)
def main():
try:
fn = sys.argv[1]
except IndexError:
fn = 'board.jpg'
src = cv.imread(cv.samples.findFile(fn))
if src is None:
print("Error loading image")
return
ed = cv.ximgproc.createEdgeDrawing()
# Set parameters (refer to the documentation for all parameters)
EDParams = cv.ximgproc_EdgeDrawing_Params()
EDParams.MinPathLength = 10 # try changing this value by pressing '/' and '*' keys
EDParams.MinLineLength = 10 # try changing this value by pressing '+' and '-' keys
EDParams.PFmode = False # default value is False, try switching by pressing 'p' key
EDParams.NFAValidation = True # default value is True, try switching by pressing 'n' key
convert_to_gray = True
key = 0
while key != 27:
ed.setParams(EDParams)
EdgeDrawingDemo(src, ed, EDParams, convert_to_gray)
key = cv.waitKey()
if key == 32: # space key
convert_to_gray = not convert_to_gray
if key == 112: # 'p' key
EDParams.PFmode = not EDParams.PFmode
if key == 110: # 'n' key
EDParams.NFAValidation = not EDParams.NFAValidation
if key == 43: # '+' key
EDParams.MinLineLength = EDParams.MinLineLength + 5
if key == 45: # '-' key
EDParams.MinLineLength = max(0, EDParams.MinLineLength - 5)
if key == 47: # '/' key
EDParams.MinPathLength = EDParams.MinPathLength + 20
if key == 42: # '*' key
EDParams.MinPathLength = max(0, EDParams.MinPathLength - 20)
if key == 115: # 's' key
fs = cv.FileStorage("ed-params.xml",cv.FileStorage_WRITE)
EDParams.write(fs)
fs.release()
print("parameters saved to ed-params.xml")
if key == 108: # 'l' key
fs = cv.FileStorage("ed-params.xml",cv.FileStorage_READ)
if fs.isOpened():
EDParams.read(fs.root())
fs.release()
print("parameters loaded from ed-params.xml")
if __name__ == '__main__':
print(__doc__)
main()
cv.destroyAllWindows()
@@ -0,0 +1,185 @@
/* edge_drawing.cpp
This example illustrates how to use cv.ximgproc.EdgeDrawing class.
It uses the OpenCV library to load an image, and then use the EdgeDrawing class
to detect edges, lines, and ellipses. The detected features are then drawn and displayed.
The main loop allows the user changing parameters of EdgeDrawing by pressing following keys:
to toggle the grayscale conversion press 'space' key
to increase MinPathLength value press '/' key
to decrease MinPathLength value press '*' key
to increase MinLineLength value press '+' key
to decrease MinLineLength value press '-' key
to toggle NFAValidation value press 'n' key
to toggle PFmode value press 'p' key
to save parameters to file press 's' key
to load parameters from file press 'l' key
The program exits when the Esc key is pressed.
*/
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/ximgproc.hpp>
#include <iostream>
void EdgeDrawingDemo(const cv::Mat src, cv::Ptr<cv::ximgproc::EdgeDrawing> ed, bool convert_to_gray);
void EdgeDrawingDemo(const cv::Mat src, cv::Ptr<cv::ximgproc::EdgeDrawing> ed, bool convert_to_gray)
{
cv::Mat ssrc = cv::Mat::zeros(src.size(), src.type());
cv::Mat lsrc = src.clone();
cv::Mat esrc = src.clone();
std::cout << std::endl << "convert_to_gray: " << convert_to_gray << std::endl;
std::cout << "MinPathLength: " << ed->params.MinPathLength << std::endl;
std::cout << "MinLineLength: " << ed->params.MinLineLength << std::endl;
std::cout << "PFmode: " << ed->params.PFmode << std::endl;
std::cout << "NFAValidation: " << ed->params.NFAValidation << std::endl;
cv::TickMeter tm;
tm.start();
cv::Mat img_to_detect;
if (convert_to_gray)
{
cv::cvtColor(src, img_to_detect, cv::COLOR_BGR2GRAY);
}
else
{
img_to_detect = src;
}
cv::imshow("source image", img_to_detect);
tm.start();
// Detect edges
ed->detectEdges(img_to_detect);
std::vector<std::vector<cv::Point>> segments = ed->getSegments();
std::vector<cv::Vec4f> lines;
ed->detectLines(lines);
std::vector<cv::Vec6d> ellipses;
ed->detectEllipses(ellipses);
tm.stop();
cv::RNG& rng = cv::theRNG();
cv::setRNGSeed(0);
// Draw detected edge segments
for (const auto& segment : segments)
{
cv::Scalar color(rng.uniform(0, 256), rng.uniform(0, 256), rng.uniform(0, 256));
cv::polylines(ssrc, segment, false, color, 1, cv::LINE_8);
}
cv::imshow("detected edge segments", ssrc);
// Draw detected lines
if (!lines.empty()) // Check if the lines have been found and only then iterate over these and add them to the image
{
for (size_t i = 0; i < lines.size(); i++)
{
cv::line(lsrc, cv::Point2d(lines[i][0], lines[i][1]), cv::Point2d(lines[i][2], lines[i][3]), cv::Scalar(0, 0, 255), 1, cv::LINE_AA);
}
}
cv::imshow("detected lines", lsrc);
// Draw detected circles and ellipses
if (!ellipses.empty()) // Check if circles and ellipses have been found and only then iterate over these and add them to the image
{
for (const auto& ellipse : ellipses)
{
cv::Point center((int)ellipse[0], (int)ellipse[1]);
cv::Size axes((int)ellipse[2] + (int)ellipse[3], (int)ellipse[2] + (int)ellipse[4]);
double angle(ellipse[5]);
cv::Scalar color = (ellipse[2] == 0) ? cv::Scalar(0, 255, 0) : cv::Scalar(0, 0, 255);
cv::ellipse(esrc, center, axes, angle, 0, 360, color, 1, cv::LINE_AA);
}
}
cv::imshow("detected circles and ellipses", esrc);
std::cout << "Total Detection Time : " << tm.getTimeMilli() << "ms." << std::endl;
}
int main(int argc, char** argv)
{
std::string filename = (argc > 1) ? argv[1] : "board.jpg";
cv::Mat src = cv::imread(cv::samples::findFile(filename));
if (src.empty())
{
std::cerr << "Error: Could not open or find the image!" << std::endl;
return -1;
}
cv::Ptr<cv::ximgproc::EdgeDrawing> ed = cv::ximgproc::createEdgeDrawing();
// Set parameters (refer to the documentation for all parameters)
ed->params.MinPathLength = 10; // try changing this value by pressing '/' and '*' keys
ed->params.MinLineLength = 10; // try changing this value by pressing '+' and '-' keys
ed->params.PFmode = false; // default value is false, try switching by pressing 'p' key
ed->params.NFAValidation = true; // default value is true, try switching by pressing 'n' key
bool convert_to_gray = true;
int key = 0;
while (key != 27)
{
EdgeDrawingDemo(src, ed, convert_to_gray);
key = cv::waitKey(0);
switch (key)
{
case 32: // space key
convert_to_gray = !convert_to_gray;
break;
case 'p': // 'p' key
ed->params.PFmode = !ed->params.PFmode;
break;
case 'n': // 'n' key
ed->params.NFAValidation = !ed->params.NFAValidation;
break;
case '+': // '+' key
ed->params.MinLineLength = std::max(0, ed->params.MinLineLength + 5);
break;
case '-': // '-' key
ed->params.MinLineLength = std::max(0, ed->params.MinLineLength - 5);
break;
case '/': // '/' key
ed->params.MinPathLength += 20;
break;
case '*': // '*' key
ed->params.MinPathLength = std::max(0, ed->params.MinPathLength - 20);
break;
case 's': // 's' key
{
cv::FileStorage fs("ed-params.xml", cv::FileStorage::WRITE);
ed->params.write(fs);
fs.release();
std::cout << "Parameters saved to ed-params.xml" << std::endl;
}
break;
case 'l': // 'l' key
{
cv::FileStorage fs("ed-params.xml", cv::FileStorage::READ);
if (fs.isOpened())
{
ed->params.read(fs.root());
fs.release();
std::cout << "Parameters loaded from ed-params.xml" << std::endl;
}
}
break;
default:
break;
}
}
return 0;
}
@@ -0,0 +1,96 @@
/*
By downloading, copying, installing or using the software you agree to this
license. If you do not agree to this license, do not download, install,
copy or use the software.
License Agreement
For Open Source Computer Vision Library
(3-clause BSD License)
Copyright (C) 2013, OpenCV Foundation, all rights reserved.
Third party copyrights are property of their respective owners.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the names of the copyright holders nor the names of the contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
This software is provided by the copyright holders and contributors "as is" and
any express or implied warranties, including, but not limited to, the implied
warranties of merchantability and fitness for a particular purpose are
disclaimed. In no event shall copyright holders or contributors be liable for
any direct, indirect, incidental, special, exemplary, or consequential damages
(including, but not limited to, procurement of substitute goods or services;
loss of use, data, or profits; or business interruption) however caused
and on any theory of liability, whether in contract, strict liability,
or tort (including negligence or otherwise) arising in any way out of
the use of this software, even if advised of the possibility of such damage.
*/
#include "opencv2/ximgproc.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>
using namespace std;
using namespace cv;
using namespace cv::ximgproc;
static void help()
{
std::cout << std::endl <<
"This sample demonstrates structured edge detection and edgeboxes." << std::endl <<
"Usage:" << std::endl <<
"./edgeboxes_demo [<model>] [<input_image>]" << std::endl;
}
int main(int argc, char **argv)
{
if (argc < 3)
{
help();
return -1;
}
Ptr<StructuredEdgeDetection> pDollar = createStructuredEdgeDetection(argv[1]);
Mat im;
im = imread(argv[2]);
Mat rgb_im;
cvtColor(im, rgb_im, COLOR_BGR2RGB);
rgb_im.convertTo(rgb_im, CV_32F, 1.0 / 255.0f);
Mat edge_im;
pDollar->detectEdges(rgb_im, edge_im);
// computes orientation from edge map
Mat O;
pDollar->computeOrientation(edge_im, O);
// apply edge nms
Mat edge_nms;
pDollar->edgesNms(edge_im, O, edge_nms, 2, 0, 1, true);
std::vector<Rect> boxes;
Ptr<EdgeBoxes> edgeboxes = createEdgeBoxes();
edgeboxes->setMaxBoxes(30);
edgeboxes->getBoundingBoxes(edge_nms, O, boxes);
for(int i = 0; i < (int)boxes.size(); i++)
{
Point p1(boxes[i].x, boxes[i].y), p2(boxes[i].x + boxes[i].width, boxes[i].y + boxes[i].height);
Scalar color(0, 255, 0);
rectangle(im, p1, p2, color, 1);
}
imshow("Edge", edge_im);
imshow("Nms", edge_nms);
imshow("Image & boxes", im);
waitKey(0);
return 0;
}
@@ -0,0 +1,45 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
This sample demonstrates structured edge detection and edgeboxes.
Usage:
edgeboxes_demo.py [<model>] [<input_image>]
'''
import cv2 as cv
import numpy as np
import sys
if __name__ == '__main__':
print(__doc__)
model = sys.argv[1]
im = cv.imread(sys.argv[2])
edge_detection = cv.ximgproc.createStructuredEdgeDetection(model)
rgb_im = cv.cvtColor(im, cv.COLOR_BGR2RGB)
edges = edge_detection.detectEdges(np.float32(rgb_im) / 255.0)
orimap = edge_detection.computeOrientation(edges)
edges = edge_detection.edgesNms(edges, orimap)
edge_boxes = cv.ximgproc.createEdgeBoxes()
edge_boxes.setMaxBoxes(30)
boxes = edge_boxes.getBoundingBoxes(edges, orimap)
boxes, scores = edge_boxes.getBoundingBoxes(edges, orimap)
if len(boxes) > 0:
boxes_scores = zip(boxes, scores)
for b_s in boxes_scores:
box = b_s[0]
x, y, w, h = box
cv.rectangle(im, (x, y), (x+w, y+h), (0, 255, 0), 1, cv.LINE_AA)
score = b_s[1][0]
cv.putText(im, "{:.2f}".format(score), (x, y), cv.FONT_HERSHEY_PLAIN, 0.8, (255, 255, 255), 1, cv.LINE_AA)
print("Box at (x,y)=({:d},{:d}); score={:f}".format(x, y, score))
cv.imshow("edges", edges)
cv.imshow("edgeboxes", im)
cv.waitKey(0)
cv.destroyAllWindows()
@@ -0,0 +1,42 @@
#include <iostream>
#include <opencv2/highgui.hpp>
#include <opencv2/ximgproc.hpp>
#include <string>
using namespace cv;
int main(int argc, char **argv)
{
cv::CommandLineParser parser(
argc, argv,
"{help h ? | | help message}"
"{@image | | Image filename to process }");
if (parser.has("help") || !parser.has("@image"))
{
parser.printMessage();
return 0;
}
// Load image from first parameter
std::string filename = parser.get<std::string>("@image");
Mat image = imread(filename, 1), res;
if (!image.data)
{
std::cerr << "No image data at " << filename << std::endl;
throw;
}
// Before filtering
imshow("Original image", image);
waitKey(0);
// Initialize filter. Kernel size 5x5, threshold 20
ximgproc::edgePreservingFilter(image, res, 9, 20);
// After filtering
imshow("Filtered image", res);
waitKey(0);
return 0;
}
@@ -0,0 +1,318 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2015, Smart Engines Ltd, all rights reserved.
// Copyright (C) 2015, Institute for Information Transmission Problems of the Russian Academy of Sciences (Kharkevich Institute), all rights reserved.
// Copyright (C) 2015, Dmitry Nikolaev, Simon Karpenko, Michail Aliev, Elena Kuznetsova, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/core/utility.hpp>
#include <opencv2/ximgproc.hpp>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <ctime>
#include <vector>
using namespace cv;
using namespace cv::ximgproc;
using namespace std;
static void help()
{
cout << "\nThis program demonstrates line finding with the Fast Hough transform.\n"
"Usage:\n"
"./fasthoughtransform\n"
"<image_name>, default is '../../../samples/data/building.jpg'\n"
"<fht_image_depth>, default is " << CV_32S << "\n"
"<fht_angle_range>, default is " << 6 << " (@see cv::AngleRangeOption)\n"
"<fht_operator>, default is " << 2 << " (@see cv::HoughOp)\n"
"<fht_makeskew>, default is " << 1 << "(@see cv::HoughDeskewOption)" << endl;
}
static bool parseArgs(int argc, const char **argv,
Mat &img,
int &houghDepth,
int &houghAngleRange,
int &houghOperator,
int &houghSkew)
{
if (argc > 6)
{
cout << "Too many arguments" << endl;
return false;
}
const char *filename = argc >= 2 ? argv[1]
: "../../../samples/data/building.jpg";
img = imread(filename, 0);
if (img.empty())
{
cout << "Failed to load image from '" << filename << "'" << endl;
return false;
}
houghDepth = argc >= 3 ? atoi(argv[2]) : CV_32S;
houghAngleRange = argc >= 4 ? atoi(argv[3]) : 6;//ARO_315_135
houghOperator = argc >= 5 ? atoi(argv[4]) : 2;//FHT_ADD
houghSkew = argc >= 6 ? atoi(argv[5]) : 1;//HDO_DESKEW
return true;
}
static bool getEdges(const Mat &src, Mat &dst)
{
Mat ucharSingleSrc;
src.convertTo(ucharSingleSrc, CV_8UC1);
Canny(ucharSingleSrc, dst, 50, 200, 3);
return true;
}
static bool fht(const Mat &src, Mat &dst,
int dstDepth, int angleRange, int op, int skew)
{
clock_t clocks = clock();
FastHoughTransform(src, dst, dstDepth, angleRange, op, skew);
clocks = clock() - clocks;
double secs = (double)clocks / CLOCKS_PER_SEC;
cout << std::setprecision(2) << "FastHoughTransform finished in " << secs
<< " seconds" << endl;
return true;
}
template<typename T>
bool rel(pair<T, Point> const &a, pair<T, Point> const &b)
{
return a.first > b.first;
}
template<typename T>
bool incIfGreater(const T& a, const T& b, int *value)
{
if (!value || a < b)
return false;
if (a > b)
++(*value);
return true;
}
static const int MAX_LEN = 10000;
template<typename T>
bool getLocalExtr(vector<Vec4i> &lines,
const Mat &src,
const Mat &fht,
float minWeight,
int maxCount)
{
vector<pair<T, Point> > weightedPoints;
for (int y = 0; y < fht.rows; ++y)
{
if (weightedPoints.size() > MAX_LEN)
break;
T const *pLine = (T *)fht.ptr(max(y - 1, 0));
T const *cLine = (T *)fht.ptr(y);
T const *nLine = (T *)fht.ptr(min(y + 1, fht.rows - 1));
for (int x = 0; x < fht.cols; ++x)
{
if (weightedPoints.size() > MAX_LEN)
break;
T const value = cLine[x];
if (value >= minWeight)
{
int isLocalMax = 0;
for (int xx = max(x - 1, 0);
xx <= min(x + 1, fht.cols - 1);
++xx)
{
if (!incIfGreater(value, pLine[xx], &isLocalMax) ||
!incIfGreater(value, cLine[xx], &isLocalMax) ||
!incIfGreater(value, nLine[xx], &isLocalMax))
{
isLocalMax = 0;
break;
}
}
if (isLocalMax > 0)
weightedPoints.push_back(make_pair(value, Point(x, y)));
}
}
}
if (weightedPoints.empty())
return true;
sort(weightedPoints.begin(), weightedPoints.end(), &rel<T>);
weightedPoints.resize(min(static_cast<int>(weightedPoints.size()),
maxCount));
for (size_t i = 0; i < weightedPoints.size(); ++i)
{
lines.push_back(HoughPoint2Line(weightedPoints[i].second, src));
}
return true;
}
static bool getLocalExtr(vector<Vec4i> &lines,
const Mat &src,
const Mat &fht,
float minWeight,
int maxCount)
{
int const depth = CV_MAT_DEPTH(fht.type());
switch (depth)
{
case 0:
return getLocalExtr<uchar>(lines, src, fht, minWeight, maxCount);
case 1:
return getLocalExtr<schar>(lines, src, fht, minWeight, maxCount);
case 2:
return getLocalExtr<ushort>(lines, src, fht, minWeight, maxCount);
case 3:
return getLocalExtr<short>(lines, src, fht, minWeight, maxCount);
case 4:
return getLocalExtr<int>(lines, src, fht, minWeight, maxCount);
case 5:
return getLocalExtr<float>(lines, src, fht, minWeight, maxCount);
case 6:
return getLocalExtr<double>(lines, src, fht, minWeight, maxCount);
default:
return false;
}
}
static void rescale(Mat const &src, Mat &dst,
int const maxHeight=500,
int const maxWidth = 1000)
{
double scale = min(min(static_cast<double>(maxWidth) / src.cols,
static_cast<double>(maxHeight) / src.rows), 1.0);
resize(src, dst, Size(), scale, scale, INTER_LINEAR_EXACT);
}
static void showHumanReadableImg(string const &name, Mat const &img)
{
Mat ucharImg;
img.convertTo(ucharImg, CV_MAKETYPE(CV_8U, img.channels()));
rescale(ucharImg, ucharImg);
imshow(name, ucharImg);
}
static void showFht(Mat const &fht)
{
double minv(0), maxv(0);
minMaxLoc(fht, &minv, &maxv);
Mat ucharFht;
fht.convertTo(ucharFht, CV_MAKETYPE(CV_8U, fht.channels()),
255.0 / (maxv + minv), minv / (maxv + minv));
rescale(ucharFht, ucharFht);
imshow("fast hough transform", ucharFht);
}
static void showLines(Mat const &src, vector<Vec4i> const &lines)
{
Mat bgrSrc;
cvtColor(src, bgrSrc, COLOR_GRAY2BGR);
for (size_t i = 0; i < lines.size(); ++i)
{
Vec4i const &l = lines[i];
line(bgrSrc, Point(l[0], l[1]), Point(l[2], l[3]),
Scalar(0, 0, 255), 1, LINE_AA);
}
rescale(bgrSrc, bgrSrc);
imshow("lines", bgrSrc);
}
int main(int argc, const char **argv)
{
Mat src;
int depth(0);
int angleRange(0);
int op(0);
int skew(0);
if (!parseArgs(argc, argv, src, depth, angleRange, op, skew))
{
help();
return -1;
}
showHumanReadableImg("src", src);
Mat canny;
if (!getEdges(src, canny))
{
cout << "Failed to select canny edges";
return -2;
}
showHumanReadableImg("canny", canny);
Mat hough;
if (!fht(canny, hough, depth, angleRange, op, skew))
{
cout << "Failed to compute Fast Hough Transform";
return -2;
}
showFht(hough);
vector<Vec4i> lines;
if (!getLocalExtr(lines, canny, hough,
static_cast<float>(255 * 0.3 * min(src.rows, src.cols)),
50))
{
cout << "Failed to find local maximums on FHT image";
return -2;
}
showLines(canny, lines);
waitKey();
return 0;
}
+105
View File
@@ -0,0 +1,105 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2017, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "opencv2/core/utility.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/ximgproc.hpp"
#include <stdio.h>
using namespace cv;
using namespace std;
int main( int argc, const char** argv)
{
float alpha = 1.0f;
float sigma = 0.02f;
int rows0 = 480;
int niters = 10;
Mat frame, src, dst;
const char* window_name = "Anisodiff : Exponential Flux";
VideoCapture cap;
if( argc > 1 )
cap.open(argv[1]);
else
cap.open(0);
if (!cap.isOpened())
{
printf("Cannot initialize video capturing\n");
return 0;
}
// Create a window
namedWindow(window_name, 1);
// create a toolbar
createTrackbar("No. of time steps", window_name, &niters, 30, 0);
for(;;)
{
cap >> frame;
if( frame.empty() )
break;
if( frame.rows <= rows0 )
src = frame;
else
resize(frame, src, Size(cvRound(480.*frame.cols/frame.rows), 480), 0, 0, INTER_LINEAR_EXACT);
float t = (float)getTickCount();
ximgproc::anisotropicDiffusion(src, dst, alpha, sigma, niters);
t = (float)getTickCount() - t;
printf("time: %.1fms\n", t*1000./getTickFrequency());
imshow(window_name, dst);
// Wait for a key stroke; the same function arranges events processing
char c = (char)waitKey(30);
if(c >= 0)
break;
}
return 0;
}
@@ -0,0 +1,50 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include <iostream>
#include <opencv2/imgproc.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/ximgproc.hpp>
#include <opencv2/highgui.hpp>
using namespace cv;
int main() {
// load image
Mat img = imread(samples::findFile("stuff.jpg"), IMREAD_COLOR);
// check if image is loaded
if (img.empty()) {
std::cout << "fail to open image" << std::endl;
return EXIT_FAILURE;
}
// create output array
std::vector<Vec6f> ells;
// test ellipse detection
cv::ximgproc::findEllipses(img, ells, 0.4f, 0.7f, 0.02f);
// print output
for (unsigned i = 0; i < ells.size(); i++) {
Vec6f ell = ells[i];
std::cout << ell << std::endl;
Scalar color(0, 0, 255);
// draw ellipse on image
ellipse(
img,
Point(cvRound(ell[0]), cvRound(ell[1])),
Size(cvRound(ell[2]), cvRound(ell[3])),
ell[5] * 180 / CV_PI, 0.0, 360.0, color, 3
);
}
// show image
imshow("result", img);
waitKey();
// end
return 0;
}
+46
View File
@@ -0,0 +1,46 @@
#!/usr/bin/python
'''
This example illustrates how to use cv.ximgproc.findEllipses function.
Usage:
find_ellipses.py [<image_name>]
image argument defaults to stuff.jpg
'''
# Python 2/3 compatibility
from __future__ import print_function
import numpy as np
import cv2 as cv
import sys
import math
def main():
try:
fn = sys.argv[1]
except IndexError:
fn = 'stuff.jpg'
src = cv.imread(cv.samples.findFile(fn))
cv.imshow("source", src)
ells = cv.ximgproc.findEllipses(src,scoreThreshold = 0.4, reliabilityThreshold = 0.7, centerDistanceThreshold = 0.02)
if ells is not None:
for i in range(len(ells)):
center = (int(ells[i][0][0]), int(ells[i][0][1]))
axes = (int(ells[i][0][2]),int(ells[i][0][3]))
angle = ells[i][0][5] * 180 / math.pi
color = (0, 0, 255)
cv.ellipse(src, center, axes, angle,0, 360, color, 2, cv.LINE_AA)
cv.imshow("detected ellipses", src)
cv.waitKey(0)
print('Done')
if __name__ == '__main__':
print(__doc__)
main()
cv.destroyAllWindows()
@@ -0,0 +1,29 @@
# USAGE - How to run this code ?
# python find_shapes.py --image shapes.png
#python findredlinedpolygonfromgooglemaps.py --image stanford.png
import numpy as np
import argparse
import cv2 as cv
# construct the argument parse and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", help = "path to the image file")
args = vars(ap.parse_args())
# load the image
image = cv.imread(args["image"])
lower = np.array([20,0,155])
upper = np.array([255,120,250])
shapeMask = cv.inRange(image, lower, upper)
# find the contours in the mask
(cnts, _) = cv.findContours(shapeMask.copy(), cv.RETR_EXTERNAL,
cv.CHAIN_APPROX_SIMPLE)
cv.imshow("Mask", shapeMask)
# loop over the contours
for c in cnts:
cv.drawContours(image, [c], -1, (0, 255, 0), 2)
cv.imshow("Image", image)
cv.waitKey(0)
+78
View File
@@ -0,0 +1,78 @@
#include <iostream>
#include "opencv2/imgproc.hpp"
#include "opencv2/ximgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
using namespace std;
using namespace cv;
using namespace cv::ximgproc;
int main(int argc, char** argv)
{
string in;
CommandLineParser parser(argc, argv, "{@input|corridor.jpg|input image}{help h||show help message}");
if (parser.has("help"))
{
parser.printMessage();
return 0;
}
in = samples::findFile(parser.get<string>("@input"));
Mat image = imread(in, IMREAD_GRAYSCALE);
if( image.empty() )
{
parser.printMessage();
return -1;
}
// Create FLD detector
// Param Default value Description
// length_threshold 10 - Segments shorter than this will be discarded
// distance_threshold 1.41421356 - A point placed from a hypothesis line
// segment farther than this will be
// regarded as an outlier
// canny_th1 50 - First threshold for
// hysteresis procedure in Canny()
// canny_th2 50 - Second threshold for
// hysteresis procedure in Canny()
// canny_aperture_size 3 - Aperturesize for the sobel operator in Canny().
// If zero, Canny() is not applied and the input
// image is taken as an edge image.
// do_merge false - If true, incremental merging of segments
// will be performed
int length_threshold = 10;
float distance_threshold = 1.41421356f;
double canny_th1 = 50.0;
double canny_th2 = 50.0;
int canny_aperture_size = 3;
bool do_merge = false;
Ptr<FastLineDetector> fld = createFastLineDetector(length_threshold,
distance_threshold, canny_th1, canny_th2, canny_aperture_size,
do_merge);
vector<Vec4f> lines;
// Because of some CPU's power strategy, it seems that the first running of
// an algorithm takes much longer. So here we run the algorithm 5 times
// to see the algorithm's processing time with sufficiently warmed-up
// CPU performance.
for (int run_count = 0; run_count < 5; run_count++) {
double freq = getTickFrequency();
lines.clear();
int64 start = getTickCount();
// Detect the lines with FLD
fld->detect(image, lines);
double duration_ms = double(getTickCount() - start) * 1000 / freq;
cout << "Elapsed time for FLD " << duration_ms << " ms." << endl;
}
// Show found lines with FLD
Mat line_image_fld(image);
fld->drawSegments(line_image_fld, lines);
imshow("FLD result", line_image_fld);
waitKey();
return 0;
}
@@ -0,0 +1,187 @@
#include <opencv2/core.hpp>
#include <opencv2/core/utility.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/geometry.hpp>
#include <opencv2/ximgproc.hpp>
#include <iostream>
using namespace cv;
using namespace std;
struct ThParameters {
int levelNoise;
int angle;
int scale10;
int origin;
int xg;
int yg;
bool update;
} ;
static vector<Point> NoisyPolygon(vector<Point> pRef, double n);
static void UpdateShape(int , void *r);
static void AddSlider(String sliderName, String windowName, int minSlider, int maxSlider, int valDefault, int *valSlider, void(*f)(int, void *), void *r);
int main(void)
{
vector<Point> ctrRef;
vector<Point> ctrRotate, ctrNoisy, ctrNoisyRotate, ctrNoisyRotateShift;
// build a shape with 5 vertex
ctrRef.push_back(Point(250,250)); ctrRef.push_back(Point(400, 250));
ctrRef.push_back(Point(400, 300)); ctrRef.push_back(Point(250, 300));ctrRef.push_back(Point(180, 270));
Point cg(0,0);
for (int i=0;i<static_cast<int>(ctrRef.size());i++)
cg+=ctrRef[i];
cg.x /= static_cast<int>(ctrRef.size());
cg.y /= static_cast<int>(ctrRef.size());
ThParameters p;
p.levelNoise=6;
p.angle=45;
p.scale10=5;
p.origin=10;
p.xg=150;
p.yg=150;
p.update=true;
namedWindow("FD Curve matching");
// A rotation with center at (150,150) of angle 45 degrees and a scaling of 5/10
AddSlider("Noise", "FD Curve matching", 0, 20, p.levelNoise, &p.levelNoise, UpdateShape, &p);
AddSlider("Angle", "FD Curve matching", 0, 359, p.angle, &p.angle, UpdateShape, &p);
AddSlider("Scale", "FD Curve matching", 5, 100, p.scale10, &p.scale10, UpdateShape, &p);
AddSlider("Origin%%", "FD Curve matching", 0, 100, p.origin, &p.origin, UpdateShape, &p);
AddSlider("Xg", "FD Curve matching", 150, 450, p.xg, &p.xg, UpdateShape, &p);
AddSlider("Yg", "FD Curve matching", 150, 450, p.yg, &p.yg, UpdateShape, &p);
int code=0;
double dist;
vector<vector<Point> > c;
Mat img;
cout << "******************** PRESS g TO MATCH CURVES *************\n";
do
{
code = waitKey(30);
if (p.update)
{
Mat r = getRotationMatrix2D(Point(p.xg, p.yg), p.angle, 10.0/ p.scale10);
ctrNoisy= NoisyPolygon(ctrRef,static_cast<double>(p.levelNoise));
cv::transform(ctrNoisy, ctrNoisyRotate, r);
ctrNoisyRotateShift.clear();
for (int i=0;i<static_cast<int>(ctrNoisy.size());i++)
ctrNoisyRotateShift.push_back(ctrNoisyRotate[(i+(p.origin*ctrNoisy.size())/100)% ctrNoisy.size()]);
// To draw contour using drawcontours
c.clear();
c.push_back(ctrRef);
c.push_back(ctrNoisyRotateShift);
p.update = false;
Rect rglobal;
for (int i = 0; i < static_cast<int>(c.size()); i++)
{
rglobal = boundingRect(c[i]) | rglobal;
}
rglobal.width += 10;
rglobal.height += 10;
img = Mat::zeros(2 * rglobal.height, 2 * rglobal.width, CV_8UC(3));
drawContours(img, c, 0, Scalar(255,0,0));
drawContours(img, c, 1, Scalar(0, 255, 0));
circle(img, c[0][0], 5, Scalar(255, 0, 0));
circle(img, c[1][0], 5, Scalar(0, 255, 0));
imshow("FD Curve matching", img);
}
if (code == 'd')
{
destroyWindow("FD Curve matching");
namedWindow("FD Curve matching");
// A rotation with center at (150,150) of angle 45 degrees and a scaling of 5/10
AddSlider("Noise", "FD Curve matching", 0, 20, p.levelNoise, &p.levelNoise, UpdateShape, &p);
AddSlider("Angle", "FD Curve matching", 0, 359, p.angle, &p.angle, UpdateShape, &p);
AddSlider("Scale", "FD Curve matching", 5, 100, p.scale10, &p.scale10, UpdateShape, &p);
AddSlider("Origin%%", "FD Curve matching", 0, 100, p.origin, &p.origin, UpdateShape, &p);
AddSlider("Xg", "FD Curve matching", 150, 450, p.xg, &p.xg, UpdateShape, &p);
AddSlider("Yg", "FD Curve matching", 150, 450, p.yg, &p.yg, UpdateShape, &p);
}
if (code == 'g')
{
ximgproc::ContourFitting fit;
vector<Point2f> ctrRef2d, ctrRot2d;
// sampling contour we want 256 points
ximgproc::contourSampling(ctrRef, ctrRef2d, 256); // use a mat
ximgproc::contourSampling(ctrNoisyRotateShift, ctrRot2d, 256); // use a vector of points
fit.setFDSize(16);
Mat t;
fit.estimateTransformation(ctrRot2d, ctrRef2d, t, &dist, false);
cout << "Transform *********\n "<<"Origin = "<< 1-t.at<double>(0,0) <<" expected "<< p.origin/100.0 <<" ("<< ctrNoisy.size()<<")\n";
cout << "Angle = " << t.at<double>(0, 1) * 180 / M_PI << " expected " << p.angle <<"\n";
cout << "Scale = " << t.at<double>(0, 2) << " expected " << p.scale10 / 10.0 << "\n";
Mat dst;
ximgproc::transformFD(ctrRot2d, t, dst, false);
c.push_back(dst);
drawContours(img, c, 2, Scalar(0,255,255));
circle(img, c[2][0], 5, Scalar(0, 255, 255));
imshow("FD Curve matching", img);
}
}
while (code!=27);
return 0;
}
vector<Point> NoisyPolygon(vector<Point> pRef, double n)
{
RNG rng;
vector<Point> c;
vector<Point> p = pRef;
vector<vector<Point> > contour;
for (int i = 0; i<static_cast<int>(p.size()); i++)
p[i] += Point(Point2d(n*rng.uniform((double)-1, (double)1), n*rng.uniform((double)-1, (double)1)));
if (n==0)
return p;
c.push_back(p[0]);
int minX = p[0].x, maxX = p[0].x, minY = p[0].y, maxY = p[0].y;
for (int i = 0; i <static_cast<int>(p.size()); i++)
{
int next = i + 1;
if (next == static_cast<int>(p.size()))
next = 0;
Point2d u = p[next] - p[i];
int d = static_cast<int>(norm(u));
double a = atan2(u.y, u.x);
int step = 1;
if (n != 0)
step = static_cast<int>(d / n);
for (int j = 1; j<d; j += max(step, 1))
{
Point pNew;
do
{
Point2d pAct = (u*j) / static_cast<double>(d);
double r = n*rng.uniform((double)0, (double)1);
double theta = a + rng.uniform(0., 2 * CV_PI);
pNew = Point(Point2d(r*cos(theta) + pAct.x + p[i].x, r*sin(theta) + pAct.y + p[i].y));
} while (pNew.x<0 || pNew.y<0);
if (pNew.x<minX)
minX = pNew.x;
if (pNew.x>maxX)
maxX = pNew.x;
if (pNew.y<minY)
minY = pNew.y;
if (pNew.y>maxY)
maxY = pNew.y;
c.push_back(pNew);
}
}
return c;
}
void UpdateShape(int , void *r)
{
((ThParameters *)r)->update = true;
}
void AddSlider(String sliderName, String windowName, int minSlider, int maxSlider, int valDefault, int *valSlider, void(*f)(int, void *), void *r)
{
createTrackbar(sliderName, windowName, valSlider, 1, f, r);
setTrackbarMin(sliderName, windowName, minSlider);
setTrackbarMax(sliderName, windowName, maxSlider);
setTrackbarPos(sliderName, windowName, valDefault);
}
@@ -0,0 +1,169 @@
import numpy as np
import cv2 as cv
import math
class ThParameters:
def __init__(self):
self.levelNoise=6
self.angle=45
self.scale10=5
self.origin=10
self.xg=150
self.yg=150
self.update=True
def UpdateShape(x ):
p.update = True
def union(a,b):
x = min(a[0], b[0])
y = min(a[1], b[1])
w = max(a[0]+a[2], b[0]+b[2]) - x
h = max(a[1]+a[3], b[1]+b[3]) - y
return (x, y, w, h)
def intersection(a,b):
x = max(a[0], b[0])
y = max(a[1], b[1])
w = min(a[0]+a[2], b[0]+b[2]) - x
h = min(a[1]+a[3], b[1]+b[3]) - y
if w<0 or h<0: return () # or (0,0,0,0) ?
return (x, y, w, h)
def NoisyPolygon(pRef,n):
# vector<Point> c
p = pRef;
# vector<vector<Point> > contour;
p = p+n*np.random.random_sample((p.shape[0],p.shape[1]))-n/2.0
if (n==0):
return p
c = np.empty(shape=[0, 2])
minX = p[0][0]
maxX = p[0][0]
minY = p[0][1]
maxY = p[0][1]
for i in range( 0,p.shape[0]):
next = i + 1;
if (next == p.shape[0]):
next = 0;
u = p[next] - p[i]
d = int(cv.norm(u))
a = np.arctan2(u[1], u[0])
step = 1
if (n != 0):
step = d // n
for j in range( 1,int(d),int(max(step, 1))):
while True:
pAct = (u*j) / (d)
r = n*np.random.random_sample()
theta = a + 2*math.pi*np.random.random_sample()
# pNew = Point(Point2d(r*cos(theta) + pAct.x + p[i].x, r*sin(theta) + pAct.y + p[i].y));
pNew = np.array([(r*np.cos(theta) + pAct[0] + p[i][0], r*np.sin(theta) + pAct[1] + p[i][1])])
if (pNew[0][0]>=0 and pNew[0][1]>=0):
break
if (pNew[0][0]<minX):
minX = pNew[0][0]
if (pNew[0][0]>maxX):
maxX = pNew[0][0]
if (pNew[0][1]<minY):
minY = pNew[0][1]
if (pNew[0][1]>maxY):
maxY = pNew[0][1]
c = np.append(c,pNew,axis = 0)
return c
#static vector<Point> NoisyPolygon(vector<Point> pRef, double n);
#static void UpdateShape(int , void *r);
#static void AddSlider(String sliderName, String windowName, int minSlider, int maxSlider, int valDefault, int *valSlider, void(*f)(int, void *), void *r);
def AddSlider(sliderName,windowName,minSlider,maxSlider,valDefault, update):
cv.createTrackbar(sliderName, windowName, valDefault,maxSlider-minSlider+1, update)
cv.setTrackbarMin(sliderName, windowName, minSlider)
cv.setTrackbarMax(sliderName, windowName, maxSlider)
cv.setTrackbarPos(sliderName, windowName, valDefault)
# vector<Point> ctrRef;
# vector<Point> ctrRotate, ctrNoisy, ctrNoisyRotate, ctrNoisyRotateShift;
# // build a shape with 5 vertex
ctrRef = np.array([(250,250),(400, 250),(400, 300),(250, 300),(180, 270)])
cg = np.mean(ctrRef,axis=0)
p=ThParameters()
cv.namedWindow("FD Curve matching");
# A rotation with center at (150,150) of angle 45 degrees and a scaling of 5/10
AddSlider("Noise", "FD Curve matching", 0, 20, p.levelNoise, UpdateShape)
AddSlider("Angle", "FD Curve matching", 0, 359, p.angle, UpdateShape)
AddSlider("Scale", "FD Curve matching", 5, 100, p.scale10, UpdateShape)
AddSlider("Origin", "FD Curve matching", 0, 100, p.origin, UpdateShape)
AddSlider("Xg", "FD Curve matching", 150, 450, p.xg, UpdateShape)
AddSlider("Yg", "FD Curve matching", 150, 450, p.yg, UpdateShape)
code = 0
img = np.zeros((300,512,3), np.uint8)
print ("******************** PRESS g TO MATCH CURVES *************\n")
while (code!=27):
code = cv.waitKey(60)
if p.update:
p.levelNoise=cv.getTrackbarPos('Noise','FD Curve matching')
p.angle=cv.getTrackbarPos('Angle','FD Curve matching')
p.scale10=cv.getTrackbarPos('Scale','FD Curve matching')
p.origin=cv.getTrackbarPos('Origin','FD Curve matching')
p.xg=cv.getTrackbarPos('Xg','FD Curve matching')
p.yg=cv.getTrackbarPos('Yg','FD Curve matching')
r = cv.getRotationMatrix2D((p.xg, p.yg), angle=p.angle, scale=10.0/ p.scale10);
ctrNoisy= NoisyPolygon(ctrRef,p.levelNoise)
ctrNoisy1 = np.reshape(ctrNoisy,(ctrNoisy.shape[0],1,2))
ctrNoisyRotate = cv.transform(ctrNoisy1,r)
ctrNoisyRotateShift = np.empty([ctrNoisyRotate.shape[0],1,2],dtype=np.int32)
for i in range(0,ctrNoisy.shape[0]):
k=(i+(p.origin*ctrNoisy.shape[0])//100)% ctrNoisyRotate.shape[0]
ctrNoisyRotateShift[i] = ctrNoisyRotate[k]
# To draw contour using drawcontours
cc= np.reshape(ctrNoisyRotateShift,[ctrNoisyRotateShift.shape[0],2])
c = [ ctrRef,cc]
p.update = False;
rglobal =(0,0,0,0)
for i in range(0,2):
r = cv.boundingRect(c[i])
rglobal = union(rglobal,r)
r = list(rglobal)
r[2] = r[2]+10
r[3] = r[3]+10
rglobal = tuple(r)
img = np.zeros((2 * rglobal[3], 2 * rglobal[2], 3), np.uint8)
cv.drawContours(img, c, 0, (255,0,0),1);
cv.drawContours(img, c, 1, (0, 255, 0),1);
cv.circle(img, tuple(c[0][0]), 5, (255, 0, 0),3);
cv.circle(img, tuple(c[1][0]), 5, (0, 255, 0),3);
cv.imshow("FD Curve matching", img);
if code == ord('d') :
cv.destroyWindow("FD Curve matching");
cv.namedWindow("FD Curve matching");
# A rotation with center at (150,150) of angle 45 degrees and a scaling of 5/10
AddSlider("Noise", "FD Curve matching", 0, 20, p.levelNoise, UpdateShape)
AddSlider("Angle", "FD Curve matching", 0, 359, p.angle, UpdateShape)
AddSlider("Scale", "FD Curve matching", 5, 100, p.scale10, UpdateShape)
AddSlider("Origin%%", "FD Curve matching", 0, 100, p.origin, UpdateShape)
AddSlider("Xg", "FD Curve matching", 150, 450, p.xg, UpdateShape)
AddSlider("Yg", "FD Curve matching", 150, 450, p.yg, UpdateShape)
if code == ord('g'):
fit = cv.ximgproc.createContourFitting(1024,16);
# sampling contour we want 256 points
cn= np.reshape(ctrRef,[ctrRef.shape[0],1,2])
ctrRef2d = cv.ximgproc.contourSampling(cn, 256)
ctrRot2d = cv.ximgproc.contourSampling(ctrNoisyRotateShift, 256)
fit.setFDSize(16)
c1 = ctrRef2d
c2 = ctrRot2d
alphaPhiST, dist = fit.estimateTransformation(ctrRot2d, ctrRef2d)
print( "Transform *********\n Origin = ", 1-alphaPhiST[0,0] ," expected ", p.origin / 100. ,"\n")
print( "Angle = ", alphaPhiST[0,1] * 180 / math.pi ," expected " , p.angle,"\n")
print( "Scale = " ,alphaPhiST[0,2] ," expected " , p.scale10 / 10.0 , "\n")
dst = cv.ximgproc.transformFD(ctrRot2d, alphaPhiST,cn, False);
ctmp= np.reshape(dst,[dst.shape[0],2])
cdst=ctmp.astype(int)
c = [ ctrRef,cc,cdst]
cv.drawContours(img, c, 2, (0,0,255),1);
cv.circle(img, (int(c[2][0][0]),int(c[2][0][1])), 5, (0, 0, 255),5);
cv.imshow("FD Curve matching", img);
@@ -0,0 +1,151 @@
/*
By downloading, copying, installing or using the software you agree to this
license. If you do not agree to this license, do not download, install,
copy or use the software.
License Agreement
For Open Source Computer Vision Library
(3-clause BSD License)
Copyright (C) 2013, OpenCV Foundation, all rights reserved.
Third party copyrights are property of their respective owners.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the names of the copyright holders nor the names of the contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
This software is provided by the copyright holders and contributors "as is" and
any express or implied warranties, including, but not limited to, the implied
warranties of merchantability and fitness for a particular purpose are
disclaimed. In no event shall copyright holders or contributors be liable for
any direct, indirect, incidental, special, exemplary, or consequential damages
(including, but not limited to, procurement of substitute goods or services;
loss of use, data, or profits; or business interruption) however caused
and on any theory of liability, whether in contract, strict liability,
or tort (including negligence or otherwise) arising in any way out of
the use of this software, even if advised of the possibility of such damage.
*/
#include "opencv2/ximgproc/segmentation.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>
using namespace cv;
using namespace cv::ximgproc::segmentation;
Scalar hsv_to_rgb(Scalar);
Scalar color_mapping(int);
static void help() {
std::cout << std::endl <<
"A program demonstrating the use and capabilities of a particular graph based image" << std::endl <<
"segmentation algorithm described in P. Felzenszwalb, D. Huttenlocher," << std::endl <<
" \"Efficient Graph-Based Image Segmentation\"" << std::endl <<
"International Journal of Computer Vision, Vol. 59, No. 2, September 2004" << std::endl << std::endl <<
"Usage:" << std::endl <<
"./graphsegmentation_demo input_image output_image [simga=0.5] [k=300] [min_size=100]" << std::endl;
}
Scalar hsv_to_rgb(Scalar c) {
Mat in(1, 1, CV_32FC3);
Mat out(1, 1, CV_32FC3);
float * p = in.ptr<float>(0);
p[0] = (float)c[0] * 360.0f;
p[1] = (float)c[1];
p[2] = (float)c[2];
cvtColor(in, out, COLOR_HSV2RGB);
Scalar t;
Vec3f p2 = out.at<Vec3f>(0, 0);
t[0] = (int)(p2[0] * 255);
t[1] = (int)(p2[1] * 255);
t[2] = (int)(p2[2] * 255);
return t;
}
Scalar color_mapping(int segment_id) {
double base = (double)(segment_id) * 0.618033988749895 + 0.24443434;
return hsv_to_rgb(Scalar(fmod(base, 1.2), 0.95, 0.80));
}
int main(int argc, char** argv) {
if (argc < 2 || argc > 6) {
help();
return -1;
}
Ptr<GraphSegmentation> gs = createGraphSegmentation();
if (argc > 3)
gs->setSigma(atof(argv[3]));
if (argc > 4)
gs->setK((float)atoi(argv[4]));
if (argc > 5)
gs->setMinSize(atoi(argv[5]));
if (!gs) {
std::cerr << "Failed to create GraphSegmentation Algorithm." << std::endl;
return -2;
}
Mat input, output, output_image;
input = imread(argv[1]);
if (!input.data) {
std::cerr << "Failed to load input image" << std::endl;
return -3;
}
gs->processImage(input, output);
double min, max;
minMaxLoc(output, &min, &max);
int nb_segs = (int)max + 1;
std::cout << nb_segs << " segments" << std::endl;
output_image = Mat::zeros(output.rows, output.cols, CV_8UC3);
uint* p;
uchar* p2;
for (int i = 0; i < output.rows; i++) {
p = output.ptr<uint>(i);
p2 = output_image.ptr<uchar>(i);
for (int j = 0; j < output.cols; j++) {
Scalar color = color_mapping(p[j]);
p2[j*3] = (uchar)color[0];
p2[j*3 + 1] = (uchar)color[1];
p2[j*3 + 2] = (uchar)color[2];
}
}
imwrite(argv[2], output_image);
std::cout << "Image written to " << argv[2] << std::endl;
return 0;
}
+231
View File
@@ -0,0 +1,231 @@
/*
* By downloading, copying, installing or using the software you agree to this license.
* If you do not agree to this license, do not download, install,
* copy or use the software.
*
*
* License Agreement
* For Open Source Computer Vision Library
* (3 - clause BSD License)
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met :
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and / or other materials provided with the distribution.
*
* * Neither the names of the copyright holders nor the names of the contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* This software is provided by the copyright holders and contributors "as is" and
* any express or implied warranties, including, but not limited to, the implied
* warranties of merchantability and fitness for a particular purpose are disclaimed.
* In no event shall copyright holders or contributors be liable for any direct,
* indirect, incidental, special, exemplary, or consequential damages
* (including, but not limited to, procurement of substitute goods or services;
* loss of use, data, or profits; or business interruption) however caused
* and on any theory of liability, whether in contract, strict liability,
* or tort(including negligence or otherwise) arising in any way out of
* the use of this software, even if advised of the possibility of such damage.
*/
#include <opencv2/core.hpp>
#include <opencv2/core/utility.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/ximgproc.hpp>
using namespace cv;
using namespace cv::ximgproc;
#include <iostream>
using namespace std;
typedef void(*FilteringOperation)(const Mat& src, Mat& dst);
//current mode (filtering operation example)
FilteringOperation g_filterOp = NULL;
//list of filtering operations
void filterDoNothing(const Mat& frame, Mat& dst);
void filterBlurring(const Mat& frame, Mat& dst);
void filterStylize(const Mat& frame, Mat& dst);
void filterDetailEnhancement(const Mat& frame8u, Mat& dst);
//common sliders for every mode
int g_sigmaColor = 25;
int g_sigmaSpatial = 10;
//for Stylizing mode
int g_edgesGamma = 100;
//for Details Enhancement mode
int g_contrastBase = 100;
int g_detailsLevel = 100;
int g_numberOfCPUs = cv::getNumberOfCPUs();
//We will use two callbacks to change parameters
void changeModeCallback(int state, void *filter);
void changeNumberOfCpuCallback(int count, void*);
void splitScreen(const Mat& rawFrame, Mat& outputFrame, Mat& srcFrame, Mat& processedFrame);
//trivial filter
void filterDoNothing(const Mat& frame, Mat& dst)
{
frame.copyTo(dst);
}
//simple edge-aware blurring
void filterBlurring(const Mat& frame, Mat& dst)
{
dtFilter(frame, frame, dst, g_sigmaSpatial, g_sigmaColor, DTF_RF);
}
//stylizing filter
void filterStylize(const Mat& frame, Mat& dst)
{
//blur frame
Mat filtered;
dtFilter(frame, frame, filtered, g_sigmaSpatial, g_sigmaColor, DTF_NC);
//compute grayscale blurred frame
Mat filteredGray;
cvtColor(filtered, filteredGray, COLOR_BGR2GRAY);
//find gradients of blurred image
Mat gradX, gradY;
Sobel(filteredGray, gradX, CV_32F, 1, 0, 3, 1.0/255);
Sobel(filteredGray, gradY, CV_32F, 0, 1, 3, 1.0/255);
//compute magnitude of gradient and fit it accordingly the gamma parameter
Mat gradMagnitude;
magnitude(gradX, gradY, gradMagnitude);
cv::pow(gradMagnitude, g_edgesGamma/100.0, gradMagnitude);
//multiply a blurred frame to the value inversely proportional to the magnitude
Mat multiplier = 1.0/(1.0 + gradMagnitude);
cvtColor(multiplier, multiplier, COLOR_GRAY2BGR);
multiply(filtered, multiplier, dst, 1, dst.type());
}
void filterDetailEnhancement(const Mat& frame8u, Mat& dst)
{
Mat frame;
frame8u.convertTo(frame, CV_32F, 1.0/255);
//Decompose image to 3 Lab channels
Mat frameLab, frameLabCn[3];
cvtColor(frame, frameLab, COLOR_BGR2Lab);
split(frameLab, frameLabCn);
//Generate progressively smoother versions of the lightness channel
Mat layer0 = frameLabCn[0]; //first channel is original lightness
Mat layer1, layer2;
dtFilter(layer0, layer0, layer1, g_sigmaSpatial, g_sigmaColor, DTF_IC);
dtFilter(layer1, layer1, layer2, 2*g_sigmaSpatial, g_sigmaColor, DTF_IC);
//Compute detail layers
Mat detailLayer1 = layer0 - layer1;
Mat detailLayer2 = layer1 - layer2;
double cBase = g_contrastBase / 100.0;
double cDetails1 = g_detailsLevel / 100.0;
double cDetails2 = 2.0 - g_detailsLevel / 100.0;
//Generate lightness
double meanLigtness = mean(frameLabCn[0])[0];
frameLabCn[0] = cBase*(layer2 - meanLigtness) + meanLigtness; //fit contrast of base (most blurred) layer
frameLabCn[0] += cDetails1*detailLayer1; //add weighted sum of detail layers to new lightness
frameLabCn[0] += cDetails2*detailLayer2; //
//Update new lightness
merge(frameLabCn, 3, frameLab);
cvtColor(frameLab, frame, COLOR_Lab2BGR);
frame.convertTo(dst, CV_8U, 255);
}
void changeModeCallback(int state, void *filter)
{
if (state == 1)
g_filterOp = (FilteringOperation) filter;
}
void changeNumberOfCpuCallback(int count, void*)
{
count = std::max(1, count);
g_numberOfCPUs = count;
}
//divide screen on two parts: srcFrame and processed Frame
void splitScreen(const Mat& rawFrame, Mat& outputFrame, Mat& srcFrame, Mat& processedFrame)
{
int h = rawFrame.rows;
int w = rawFrame.cols;
int cn = rawFrame.channels();
outputFrame.create(h, 2 * w, CV_MAKE_TYPE(CV_8U, cn));
srcFrame = outputFrame(Range::all(), Range(0, w));
processedFrame = outputFrame(Range::all(), Range(w, 2 * w));
rawFrame.convertTo(srcFrame, srcFrame.type());
}
int main()
{
VideoCapture cap(0);
if (!cap.isOpened())
{
cerr << "Capture device was not found" << endl;
return -1;
}
namedWindow("Demo");
displayOverlay("Demo", "Press Ctrl+P to show property window", 5000);
//Thread trackbar
createTrackbar("Threads", String(), &g_numberOfCPUs, cv::getNumberOfCPUs(), changeNumberOfCpuCallback);
//Buttons to choose different modes
createButton("Mode Details Enhancement", changeModeCallback, (void*)filterDetailEnhancement, QT_RADIOBOX, true);
createButton("Mode Stylizing", changeModeCallback, (void*)filterStylize, QT_RADIOBOX, false);
createButton("Mode Blurring", changeModeCallback, (void*)filterBlurring, QT_RADIOBOX, false);
createButton("Mode DoNothing", changeModeCallback, (void*)filterDoNothing, QT_RADIOBOX, false);
//sliders for Details Enhancement mode
g_filterOp = filterDetailEnhancement; //set Details Enhancement as default filter
createTrackbar("Detail contrast", String(), &g_contrastBase, 200);
createTrackbar("Detail level" , String(), &g_detailsLevel, 200);
//sliders for Stylizing mode
createTrackbar("Style gamma", String(), &g_edgesGamma, 300);
//sliders for every mode
createTrackbar("Sigma Spatial", String(), &g_sigmaSpatial, 200);
createTrackbar("Sigma Color" , String(), &g_sigmaColor, 200);
Mat rawFrame, outputFrame;
Mat srcFrame, processedFrame;
for (;;)
{
do
{
cap >> rawFrame;
} while (rawFrame.empty());
cv::setNumThreads(g_numberOfCPUs); //speedup filtering
splitScreen(rawFrame, outputFrame, srcFrame, processedFrame);
g_filterOp(srcFrame, processedFrame);
imshow("Demo", outputFrame);
if (waitKey(1) == 27) break;
}
return 0;
}
@@ -0,0 +1,56 @@
/*
* C++ sample to demonstrate Niblack thresholding.
*/
#include <iostream>
#include "opencv2/core.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/ximgproc.hpp"
using namespace std;
using namespace cv;
using namespace cv::ximgproc;
Mat_<uchar> src;
int k_ = 8;
int blockSize_ = 11;
int type_ = THRESH_BINARY;
int method_ = BINARIZATION_NIBLACK;
void on_trackbar(int, void*);
int main(int argc, char** argv)
{
// read gray-scale image
if(argc != 2)
{
cout << "Usage: ./niblack_thresholding [IMAGE]\n";
return 1;
}
const char* filename = argv[1];
src = imread(filename, IMREAD_GRAYSCALE);
imshow("Source", src);
namedWindow("Niblack", WINDOW_AUTOSIZE);
createTrackbar("k", "Niblack", &k_, 20, on_trackbar);
createTrackbar("blockSize", "Niblack", &blockSize_, 30, on_trackbar);
createTrackbar("method", "Niblack", &method_, 3, on_trackbar);
createTrackbar("threshType", "Niblack", &type_, 4, on_trackbar);
on_trackbar(0, 0);
waitKey(0);
return 0;
}
void on_trackbar(int, void*)
{
double k = static_cast<double>(k_-10)/10; // [-1.0, 1.0]
int blockSize = 2*(blockSize_ >= 1 ? blockSize_ : 1) + 1; // 3,5,7,...,61
int type = type_; // THRESH_BINARY, THRESH_BINARY_INV,
// THRESH_TRUNC, THRESH_TOZERO, THRESH_TOZERO_INV
int method = method_; //BINARIZATION_NIBLACK, BINARIZATION_SAUVOLA, BINARIZATION_WOLF, BINARIZATION_NICK
Mat dst;
niBlackThreshold(src, dst, 255, type, blockSize, k, method);
imshow("Niblack", dst);
}
+112
View File
@@ -0,0 +1,112 @@
/*
* By downloading, copying, installing or using the software you agree to this license.
* If you do not agree to this license, do not download, install,
* copy or use the software.
*
*
* License Agreement
* For Open Source Computer Vision Library
* (3 - clause BSD License)
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met :
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and / or other materials provided with the distribution.
*
* * Neither the names of the copyright holders nor the names of the contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* This software is provided by the copyright holders and contributors "as is" and
* any express or implied warranties, including, but not limited to, the implied
* warranties of merchantability and fitness for a particular purpose are disclaimed.
* In no event shall copyright holders or contributors be liable for any direct,
* indirect, incidental, special, exemplary, or consequential damages
* (including, but not limited to, procurement of substitute goods or services;
* loss of use, data, or profits; or business interruption) however caused
* and on any theory of liability, whether in contract, strict liability,
* or tort(including negligence or otherwise) arising in any way out of
* the use of this software, even if advised of the possibility of such damage.
*/
#include <opencv2/core.hpp>
#include <opencv2/core/utility.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/ximgproc.hpp>
#include "opencv2/ximgproc/paillou_filter.hpp"
using namespace cv;
using namespace cv::ximgproc;
#include <iostream>
using namespace std;
int aa = 100, ww = 10;
const char* window_name = "Gradient Modulus";
static void DisplayImage(Mat x,string s)
{
vector<Mat> sx;
split(x, sx);
vector<double> minVal(3), maxVal(3);
for (int i = 0; i < static_cast<int>(sx.size()); i++)
{
minMaxLoc(sx[i], &minVal[i], &maxVal[i]);
}
maxVal[0] = *max_element(maxVal.begin(), maxVal.end());
minVal[0] = *min_element(minVal.begin(), minVal.end());
Mat uc;
x.convertTo(uc, CV_8U,255/(maxVal[0]-minVal[0]),-255*minVal[0]/(maxVal[0]-minVal[0]));
imshow(s, uc);
}
/**
* @function paillouFilter
* @brief Trackbar callback
*/
static void PaillouFilter(int, void*pm)
{
Mat img = *((Mat*)pm);
Mat dst;
double a=aa/100.0, w=ww/100.0;
Mat rx,ry;
GradientPaillouX(img, rx, a, w);
GradientPaillouY(img, ry, a, w);
DisplayImage(rx, "Gx");
DisplayImage(ry, "Gy");
add(rx.mul(rx), ry.mul(ry), dst);
sqrt(dst, dst);
DisplayImage(dst, window_name );
}
int main(int argc, char* argv[])
{
if (argc < 2)
{
cout << "usage: paillou_demo [image]" << endl;
return 1;
}
Mat img = imread(argv[1]);
if (img.empty())
{
cout << "File not found or empty image\n";
return 1;
}
imshow("Original",img);
namedWindow( window_name, WINDOW_AUTOSIZE );
/// Create a Trackbar for user to enter threshold
createTrackbar( "a:",window_name, &aa, 400, PaillouFilter, &img );
createTrackbar( "w:", window_name, &ww, 400, PaillouFilter, &img );
PaillouFilter(0, &img);
waitKey();
return 0;
}
+50
View File
@@ -0,0 +1,50 @@
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/ximgproc.hpp>
#include <iostream>
static inline cv::Mat operator& ( const cv::Mat& lhs, const cv::Matx23d& rhs )
{
cv::Mat ret;
cv::warpAffine ( lhs, ret, rhs, lhs.size(), cv::INTER_LINEAR );
return ret;
}
static inline cv::Mat operator& ( const cv::Matx23d& lhs, const cv::Mat& rhs )
{
cv::Mat ret;
cv::warpAffine ( rhs, ret, lhs, rhs.size(), cv::INTER_LINEAR | cv::WARP_INVERSE_MAP );
return ret;
}
int main(int argc, char** argv)
{
cv::CommandLineParser parser(argc, argv, "{ @input1 | ../data/peilin_plane.png | }{ @input2 | ../data/peilin_shape.png | }");
parser.about("\nThis program demonstrates Pei&Lin Normalization\n");
parser.printMessage();
std::string filename1 = parser.get<std::string>("@input1");
std::string filename2 = parser.get<std::string>("@input2");
cv::Mat I = cv::imread(filename1, 0);
if (I.empty())
{
std::cout << "Couldn't open image " << filename1 << std::endl;
return 0;
}
cv::Mat J = cv::imread(filename2, 0);
if (J.empty())
{
std::cout << "Couldn't open image " << filename2 << std::endl;
return 0;
}
cv::Mat N = I & cv::ximgproc::PeiLinNormalization ( I );
cv::Mat D = cv::ximgproc::PeiLinNormalization ( J ) & I;
cv::imshow ( "I", I );
cv::imshow ( "N", N );
cv::imshow ( "J", J );
cv::imshow ( "D", D );
cv::waitKey();
return 0;
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 662 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

@@ -0,0 +1,18 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include <opencv2/highgui.hpp>
#include <opencv2/ximgproc/radon_transform.hpp>
using namespace cv;
int main() {
Mat src = imread("peilin_plane.png", IMREAD_GRAYSCALE);
Mat radon;
ximgproc::RadonTransform(src, radon, 1, 0, 180, false, true);
imshow("src image", src);
imshow("Radon transform", radon);
waitKey();
return 0;
}
@@ -0,0 +1,13 @@
# This file is part of OpenCV project.
# It is subject to the license terms in the LICENSE file found in the top-level directory
# of this distribution and at http://opencv.org/license.html.
import numpy as np
import cv2 as cv
if __name__ == "__main__":
src = cv.imread("peilin_plane.png", cv.IMREAD_GRAYSCALE)
radon = cv.ximgproc.RadonTransform(src).astype(np.float32)
cv.imshow("src image", src)
cv.imshow("Radon transform", radon)
cv.waitKey()
@@ -0,0 +1,246 @@
#include <iostream>
#include "opencv2/imgproc.hpp"
#include "opencv2/ximgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
using namespace std;
using namespace cv;
using namespace cv::ximgproc;
// Adapted from cv_timer in cv_utilities
class Timer
{
public:
Timer() : start_(0), time_(0) {}
void start()
{
start_ = cv::getTickCount();
}
void stop()
{
CV_Assert(start_ != 0);
int64 end = cv::getTickCount();
time_ += end - start_;
start_ = 0;
}
double time()
{
double ret = time_ / cv::getTickFrequency();
time_ = 0;
return ret;
}
private:
int64 start_, time_;
};
static void help()
{
printf("\nAllows to estimate the efficiency of the morphology operations implemented\n"
"in ximgproc/run_length_morphology.cpp\n"
"Call:\n example_ximgproc_run_length_morphology_demo [image] -u=factor_upscaling image\n"
"Similar to the morphology2 sample of the main opencv library it shows the use\n"
"of rect, ellipse and cross kernels\n\n"
"As rectangular and cross-shaped structuring elements are highly optimized in opencv_imgproc module,\n"
"only with elliptical structuring elements a speedup is possible (e.g. for larger circles).\n"
"Run-length morphology has advantages for larger images.\n"
"You can verify this by upscaling your input with e.g. -u=2\n");
printf( "Hot keys: \n"
"\tESC - quit the program\n"
"\tr - use rectangle structuring element\n"
"\te - use elliptic structuring element\n"
"\tc - use cross-shaped structuring element\n"
"\tSPACE - loop through all the options\n" );
}
static void print_introduction()
{
printf("\nFirst select a threshold for binarization.\n"
"Then move the sliders for erosion/dilation or open/close operation\n\n"
"The ratio between the time of the execution from opencv_imgproc\n"
"and the code using run-length encoding will be displayed in the console\n\n");
}
Mat src, dst;
int element_shape = MORPH_ELLIPSE;
//the address of variable which receives trackbar position update
int max_size = 40;
int open_close_pos = 0;
int erode_dilate_pos = 0;
int nThreshold = 100;
cv::Mat binaryImage;
cv::Mat binaryRLE, dstRLE;
cv::Mat rlePainted;
static void PaintRLEToImage(cv::Mat& rleImage, cv::Mat& res, unsigned char uValue)
{
res = cv::Scalar(0);
rl::paint(res, rleImage, Scalar((double) uValue));
}
static bool AreImagesIdentical(cv::Mat& image1, cv::Mat& image2)
{
cv::Mat diff;
cv::absdiff(image1, image2, diff);
int nDiff = cv::countNonZero(diff);
return (nDiff == 0);
}
// callback function for open/close trackbar
static void OpenClose(int, void*)
{
int n = open_close_pos - max_size;
int an = n > 0 ? n : -n;
Mat element = getStructuringElement(element_shape, Size(an*2+1, an*2+1), Point(an, an) );
Timer timer;
timer.start();
if( n < 0 )
morphologyEx(binaryImage, dst, MORPH_OPEN, element);
else
morphologyEx(binaryImage, dst, MORPH_CLOSE, element);
timer.stop();
double imgproc_duration = timer.time();
element = rl::getStructuringElement(element_shape, Size(an * 2 + 1, an * 2 + 1));
Timer timer2;
timer2.start();
if (n < 0)
rl::morphologyEx(binaryRLE, dstRLE, MORPH_OPEN, element, true);
else
rl::morphologyEx(binaryRLE, dstRLE, MORPH_CLOSE, element, true);
timer2.stop();
double rl_duration = timer2.time();
cout << "ratio open/close duration: " << rl_duration / imgproc_duration << " (run-length: "
<< rl_duration << ", pixelwise: " << imgproc_duration << " )" << std::endl;
PaintRLEToImage(dstRLE, rlePainted, (unsigned char)255);
if (!AreImagesIdentical(dst, rlePainted))
{
cout << "error result image are not identical" << endl;
}
imshow("Open/Close", rlePainted);
}
// callback function for erode/dilate trackbar
static void ErodeDilate(int, void*)
{
int n = erode_dilate_pos - max_size;
int an = n > 0 ? n : -n;
Mat element = getStructuringElement(element_shape, Size(an*2+1, an*2+1), Point(an, an) );
Timer timer;
timer.start();
if( n < 0 )
erode(binaryImage, dst, element);
else
dilate(binaryImage, dst, element);
timer.stop();
double imgproc_duration = timer.time();
element = rl::getStructuringElement(element_shape, Size(an*2+1, an*2+1));
Timer timer2;
timer2.start();
if( n < 0 )
rl::erode(binaryRLE, dstRLE, element, true);
else
rl::dilate(binaryRLE, dstRLE, element);
timer2.stop();
double rl_duration = timer2.time();
PaintRLEToImage(dstRLE, rlePainted, (unsigned char)255);
cout << "ratio erode/dilate duration: " << rl_duration / imgproc_duration <<
" (run-length: " << rl_duration << ", pixelwise: " << imgproc_duration << " )" << std::endl;
if (!AreImagesIdentical(dst, rlePainted))
{
cout << "error result image are not identical" << endl;
}
imshow("Erode/Dilate", rlePainted);
}
static void OnChangeThreshold(int, void*)
{
threshold(src, binaryImage, (double) nThreshold, 255.0, THRESH_BINARY );
rl::threshold(src, binaryRLE, (double) nThreshold, THRESH_BINARY);
imshow("Threshold", binaryImage);
}
int main( int argc, char** argv )
{
cv::CommandLineParser parser(argc, argv, "{help h||}{ @image | ../data/aloeL.jpg | }{u| |}");
if (parser.has("help"))
{
help();
return 0;
}
std::string filename = parser.get<std::string>("@image");
cv::Mat srcIn;
if( (srcIn = imread(filename,IMREAD_GRAYSCALE)).empty() )
{
help();
return -1;
}
int nScale = 1;
if (parser.has("u"))
{
int theScale = parser.get<int>("u");
if (theScale > 1)
nScale = theScale;
}
if (nScale == 1)
src = srcIn;
else
cv::resize(srcIn, src, cv::Size(srcIn.rows * nScale, srcIn.cols * nScale));
cout << "scale factor read " << nScale << endl;
print_introduction();
//create windows for output images
namedWindow("Open/Close",1);
namedWindow("Erode/Dilate",1);
namedWindow("Threshold",1);
open_close_pos = erode_dilate_pos = max_size - 10;
createTrackbar("size s.e.", "Open/Close",&open_close_pos,max_size*2+1,OpenClose);
createTrackbar("size s.e.", "Erode/Dilate",&erode_dilate_pos,max_size*2+1,ErodeDilate);
createTrackbar("threshold", "Threshold",&nThreshold,255, OnChangeThreshold);
OnChangeThreshold(0, 0);
rlePainted.create(cv::Size(src.cols, src.rows), CV_8UC1);
for(;;)
{
OpenClose(open_close_pos, 0);
ErodeDilate(erode_dilate_pos, 0);
char c = (char)waitKey(0);
if( c == 27 )
break;
if( c == 'e' )
element_shape = MORPH_ELLIPSE;
else if( c == 'r' )
element_shape = MORPH_RECT;
else if( c == 'c' )
element_shape = MORPH_CROSS;
else if( c == ' ' )
element_shape = (element_shape + 1) % 3;
}
return 0;
}
+157
View File
@@ -0,0 +1,157 @@
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/core/utility.hpp>
#include <opencv2/ximgproc.hpp>
#include <ctype.h>
#include <stdio.h>
#include <iostream>
using namespace cv;
using namespace cv::ximgproc;
using namespace std;
void trackbarChanged(int pos, void* data);
static void help()
{
cout << "\nThis program demonstrates SEEDS superpixels using OpenCV class SuperpixelSEEDS\n"
"Use [space] to toggle output mode\n"
"\n"
"It captures either from the camera of your choice: 0, 1, ... default 0\n"
"Or from an input image\n"
"Call:\n"
"./seeds [camera #, default 0]\n"
"./seeds [input image file]\n" << endl;
}
static const char* window_name = "SEEDS Superpixels";
static bool init = false;
void trackbarChanged(int, void*)
{
init = false;
}
int main(int argc, char** argv)
{
VideoCapture cap;
Mat input_image;
bool use_video_capture = false;
help();
if( argc == 1 || (argc == 2 && strlen(argv[1]) == 1 && isdigit(argv[1][0])) )
{
cap.open(argc == 2 ? argv[1][0] - '0' : 0);
use_video_capture = true;
}
else if( argc >= 2 )
{
input_image = imread(argv[1]);
}
if( use_video_capture )
{
if( !cap.isOpened() )
{
cout << "Could not initialize capturing...\n";
return -1;
}
}
else if( input_image.empty() )
{
cout << "Could not open image...\n";
return -1;
}
namedWindow(window_name, 0);
int num_iterations = 4;
int prior = 2;
bool double_step = false;
int num_superpixels = 400;
int num_levels = 4;
int num_histogram_bins = 5;
createTrackbar("Number of Superpixels", window_name, &num_superpixels, 1000, trackbarChanged);
createTrackbar("Smoothing Prior", window_name, &prior, 5, trackbarChanged);
createTrackbar("Number of Levels", window_name, &num_levels, 10, trackbarChanged);
createTrackbar("Iterations", window_name, &num_iterations, 12, 0);
Mat result, mask;
Ptr<SuperpixelSEEDS> seeds;
int width, height;
int display_mode = 0;
for (;;)
{
Mat frame;
if( use_video_capture )
cap >> frame;
else
input_image.copyTo(frame);
if( frame.empty() )
break;
if( !init )
{
width = frame.size().width;
height = frame.size().height;
seeds = createSuperpixelSEEDS(width, height, frame.channels(), num_superpixels,
num_levels, prior, num_histogram_bins, double_step);
init = true;
}
Mat converted;
cvtColor(frame, converted, COLOR_BGR2HSV);
double t = (double) getTickCount();
seeds->iterate(converted, num_iterations);
result = frame;
t = ((double) getTickCount() - t) / getTickFrequency();
printf("SEEDS segmentation took %i ms with %3i superpixels\n",
(int) (t * 1000), seeds->getNumberOfSuperpixels());
/* retrieve the segmentation result */
Mat labels;
seeds->getLabels(labels);
/* get the contours for displaying */
seeds->getLabelContourMask(mask, false);
result.setTo(Scalar(0, 0, 255), mask);
/* display output */
switch (display_mode)
{
case 0: //superpixel contours
imshow(window_name, result);
break;
case 1: //mask
imshow(window_name, mask);
break;
case 2: //labels array
{
// use the last x bit to determine the color. Note that this does not
// guarantee that 2 neighboring superpixels have different colors.
const int num_label_bits = 2;
labels &= (1 << num_label_bits) - 1;
labels *= 1 << (16 - num_label_bits);
imshow(window_name, labels);
}
break;
}
int c = waitKey(1);
if( (c & 255) == 'q' || c == 'Q' || (c & 255) == 27 )
break;
else if( (c & 255) == ' ' )
display_mode = (display_mode + 1) % 3;
}
return 0;
}
@@ -0,0 +1,110 @@
/*
By downloading, copying, installing or using the software you agree to this
license. If you do not agree to this license, do not download, install,
copy or use the software.
License Agreement
For Open Source Computer Vision Library
(3-clause BSD License)
Copyright (C) 2013, OpenCV Foundation, all rights reserved.
Third party copyrights are property of their respective owners.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the names of the copyright holders nor the names of the contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
This software is provided by the copyright holders and contributors "as is" and
any express or implied warranties, including, but not limited to, the implied
warranties of merchantability and fitness for a particular purpose are
disclaimed. In no event shall copyright holders or contributors be liable for
any direct, indirect, incidental, special, exemplary, or consequential damages
(including, but not limited to, procurement of substitute goods or services;
loss of use, data, or profits; or business interruption) however caused
and on any theory of liability, whether in contract, strict liability,
or tort (including negligence or otherwise) arising in any way out of
the use of this software, even if advised of the possibility of such damage.
*/
#include "opencv2/ximgproc/segmentation.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>
#include <ctime>
using namespace cv;
using namespace cv::ximgproc::segmentation;
static void help() {
std::cout << std::endl <<
"A program demonstrating the use and capabilities of a particular image segmentation algorithm described" << std::endl <<
" in Jasper R. R. Uijlings, Koen E. A. van de Sande, Theo Gevers, Arnold W. M. Smeulders: " << std::endl <<
" \"Selective Search for Object Recognition\"" << std::endl <<
"International Journal of Computer Vision, Volume 104 (2), page 154-171, 2013" << std::endl << std::endl <<
"Usage:" << std::endl <<
"./selectivesearchsegmentation_demo input_image (single|fast|quality)" << std::endl <<
"Use a to display less rects, d to display more rects, q to quit" << std::endl;
}
int main(int argc, char** argv) {
if (argc < 3) {
help();
return -1;
}
Mat img = imread(argv[1]);
Ptr<SelectiveSearchSegmentation> gs = createSelectiveSearchSegmentation();
gs->setBaseImage(img);
if (argv[2][0] == 's') {
gs->switchToSingleStrategy();
} else if (argv[2][0] == 'f') {
gs->switchToSelectiveSearchFast();
} else if (argv[2][0] == 'q') {
gs->switchToSelectiveSearchQuality();
} else {
help();
return -2;
}
std::vector<Rect> rects;
gs->process(rects);
int nb_rects = 10;
char c = (char)waitKey();
while(c != 'q') {
Mat wimg = img.clone();
int i = 0;
for(std::vector<Rect>::iterator it = rects.begin(); it != rects.end(); ++it) {
if (i++ < nb_rects) {
rectangle(wimg, *it, Scalar(0, 0, 255));
}
}
imshow("Output", wimg);
c = (char)waitKey();
if (c == 'd') {
nb_rects += 10;
}
if (c == 'a' && nb_rects > 10) {
nb_rects -= 10;
}
}
return 0;
}
@@ -0,0 +1,60 @@
#!/usr/bin/env python
'''
A program demonstrating the use and capabilities of a particular image segmentation algorithm described
in Jasper R. R. Uijlings, Koen E. A. van de Sande, Theo Gevers, Arnold W. M. Smeulders:
"Selective Search for Object Recognition"
International Journal of Computer Vision, Volume 104 (2), page 154-171, 2013
Usage:
./selectivesearchsegmentation_demo.py input_image (single|fast|quality)
Use "a" to display less rects, 'd' to display more rects, "q" to quit.
'''
import cv2 as cv
import sys
if __name__ == '__main__':
img = cv.imread(sys.argv[1])
cv.setUseOptimized(True)
cv.setNumThreads(8)
gs = cv.ximgproc.segmentation.createSelectiveSearchSegmentation()
gs.setBaseImage(img)
if (sys.argv[2][0] == 's'):
gs.switchToSingleStrategy()
elif (sys.argv[2][0] == 'f'):
gs.switchToSelectiveSearchFast()
elif (sys.argv[2][0] == 'q'):
gs.switchToSelectiveSearchQuality()
else:
print(__doc__)
sys.exit(1)
rects = gs.process()
nb_rects = 10
while True:
wimg = img.copy()
for i in range(len(rects)):
if (i < nb_rects):
x, y, w, h = rects[i]
cv.rectangle(wimg, (x, y), (x+w, y+h), (0, 255, 0), 1, cv.LINE_AA)
cv.imshow("Output", wimg);
c = cv.waitKey()
if (c == 100):
nb_rects += 10
elif (c == 97 and nb_rects > 10):
nb_rects -= 10
elif (c == 113):
break
cv.destroyAllWindows()
+138
View File
@@ -0,0 +1,138 @@
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/core/utility.hpp>
#include <opencv2/ximgproc.hpp>
#include <ctype.h>
#include <stdio.h>
#include <iostream>
using namespace cv;
using namespace cv::ximgproc;
using namespace std;
static const char* window_name = "SLIC Superpixels";
static const char* keys =
"{h help | | help menu}"
"{c camera |0| camera id}"
"{i image | | image file}"
"{a algorithm |1| SLIC(0),SLICO(1),MSLIC(2)}"
;
int main(int argc, char** argv)
{
CommandLineParser cmd(argc,argv,keys);
if (cmd.has("help")) {
cmd.about("This program demonstrates SLIC superpixels using OpenCV class SuperpixelSLIC.\n"
"If no image file is supplied, try to open a webcam.\n"
"Use [space] to toggle output mode, ['q' or 'Q' or 'esc'] to exit.\n");
cmd.printMessage();
return 0;
}
int capture = cmd.get<int>("camera");
String img_file = cmd.get<String>("image");
int algorithm = cmd.get<int>("algorithm");
int region_size = 50;
int ruler = 30;
int min_element_size = 50;
int num_iterations = 3;
bool use_video_capture = img_file.empty();
VideoCapture cap;
Mat input_image;
if( use_video_capture )
{
if( !cap.open(capture) )
{
cout << "Could not initialize capturing..."<<capture<<"\n";
return -1;
}
}
else
{
input_image = imread(img_file);
if( input_image.empty() )
{
cout << "Could not open image..."<<img_file<<"\n";
return -1;
}
}
namedWindow(window_name, 0);
createTrackbar("Algorithm", window_name, &algorithm, 2, 0);
createTrackbar("Region size", window_name, &region_size, 200, 0);
createTrackbar("Ruler", window_name, &ruler, 100, 0);
createTrackbar("Connectivity", window_name, &min_element_size, 100, 0);
createTrackbar("Iterations", window_name, &num_iterations, 12, 0);
Mat result, mask;
int display_mode = 0;
for (;;)
{
Mat frame;
if( use_video_capture )
cap >> frame;
else
input_image.copyTo(frame);
if( frame.empty() )
break;
result = frame;
Mat converted;
cvtColor(frame, converted, COLOR_BGR2HSV);
double t = (double) getTickCount();
Ptr<SuperpixelSLIC> slic = createSuperpixelSLIC(converted,algorithm+SLIC,region_size,float(ruler));
slic->iterate(num_iterations);
if (min_element_size>0)
slic->enforceLabelConnectivity(min_element_size);
t = ((double) getTickCount() - t) / getTickFrequency();
cout << "SLIC" << (algorithm?'O':' ')
<< " segmentation took " << (int) (t * 1000)
<< " ms with " << slic->getNumberOfSuperpixels() << " superpixels" << endl;
// get the contours for displaying
slic->getLabelContourMask(mask, true);
result.setTo(Scalar(0, 0, 255), mask);
// display output
switch (display_mode)
{
case 0: //superpixel contours
imshow(window_name, result);
break;
case 1: //mask
imshow(window_name, mask);
break;
case 2: //labels array
{
// use the last x bit to determine the color. Note that this does not
// guarantee that 2 neighboring superpixels have different colors.
// retrieve the segmentation result
Mat labels;
slic->getLabels(labels);
const int num_label_bits = 2;
labels &= (1 << num_label_bits) - 1;
labels *= 1 << (16 - num_label_bits);
imshow(window_name, labels);
break;
}
}
int c = waitKey(1) & 0xff;
if( c == 'q' || c == 'Q' || c == 27 )
break;
else if( c == ' ' )
display_mode = (display_mode + 1) % 3;
}
return 0;
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 872 KiB

@@ -0,0 +1,96 @@
/**************************************************************************************
The structured forests for fast edge detection demo requires you to provide a model.
This model can be found at the opencv_extra repository on Github on the following link:
https://github.com/opencv/opencv_extra/blob/master/testdata/cv/ximgproc/model.yml.gz
***************************************************************************************/
#include <opencv2/ximgproc.hpp>
#include "opencv2/highgui.hpp"
#include <iostream>
using namespace cv;
using namespace cv::ximgproc;
const char* keys =
{
"{i || input image file name}"
"{m || model file name}"
"{o || output image file name}"
};
int main( int argc, const char** argv )
{
CommandLineParser parser(argc, argv, keys);
parser.about("This sample demonstrates usage of structured forests for fast edge detection");
parser.printMessage();
if ( !parser.check() )
{
parser.printErrors();
return -1;
}
String modelFilename = parser.get<String>("m");
String inFilename = parser.get<String>("i");
String outFilename = parser.get<String>("o");
//! [imread]
Mat image = imread(inFilename, IMREAD_COLOR);
if ( image.empty() )
CV_Error(Error::StsError, String("Cannot read image file: ") + inFilename);
//! [imread]
if ( modelFilename.size() == 0)
CV_Error(Error::StsError, String("Empty model name"));
//! [convert]
image.convertTo(image, DataType<float>::type, 1/255.0);
//! [convert]
TickMeter tm;
tm.start();
//! [create]
Ptr<StructuredEdgeDetection> pDollar =
createStructuredEdgeDetection(modelFilename);
//! [create]
tm.stop();
std::cout << "createStructuredEdgeDetection() time : " << tm << std::endl;
tm.reset();
tm.start();
//! [detect]
Mat edges;
pDollar->detectEdges(image, edges);
//! [detect]
tm.stop();
std::cout << "detectEdges() time : " << tm << std::endl;
tm.reset();
tm.start();
//! [nms]
// computes orientation from edge map
Mat orientation_map;
pDollar->computeOrientation(edges, orientation_map);
// suppress edges
Mat edge_nms;
pDollar->edgesNms(edges, orientation_map, edge_nms, 2, 0, 1, true);
//! [nms]
tm.stop();
std::cout << "nms time : " << tm << std::endl;
//! [imshow]
if ( outFilename.size() == 0 )
{
imshow("edges", edges);
imshow("edges nms", edge_nms);
waitKey(0);
}
else
imwrite(outFilename, 255*edges);
//! [imshow]
return 0;
}
+45
View File
@@ -0,0 +1,45 @@
#include <iostream>
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/ximgproc.hpp"
using namespace std;
using namespace cv;
int main()
{
Mat img = imread("opencv-logo.png", IMREAD_COLOR);
resize(img, img, Size(), 0.5, 0.5, INTER_LINEAR_EXACT);
/// Threshold the input image
Mat img_grayscale, img_binary;
cvtColor(img, img_grayscale,COLOR_BGR2GRAY);
threshold(img_grayscale, img_binary, 0, 255, THRESH_OTSU | THRESH_BINARY_INV);
/// Apply thinning to get a skeleton
Mat img_thinning_ZS, img_thinning_GH;
ximgproc::thinning(img_binary, img_thinning_ZS, ximgproc::THINNING_ZHANGSUEN);
ximgproc::thinning(img_binary, img_thinning_GH, ximgproc::THINNING_GUOHALL);
/// Make 3 channel images from thinning result
Mat result_ZS(img.rows, img.cols, CV_8UC3), result_GH(img.rows, img.cols, CV_8UC3);
Mat in[] = { img_thinning_ZS, img_thinning_ZS, img_thinning_ZS };
Mat in2[] = { img_thinning_GH, img_thinning_GH, img_thinning_GH };
int from_to[] = { 0,0, 1,1, 2,2 };
mixChannels( in, 3, &result_ZS, 1, from_to, 3 );
mixChannels( in2, 3, &result_GH, 1, from_to, 3 );
/// Combine everything into a canvas
Mat canvas(img.rows, img.cols * 3, CV_8UC3);
img.copyTo( canvas( Rect(0, 0, img.cols, img.rows) ) );
result_ZS.copyTo( canvas( Rect(img.cols, 0, img.cols, img.rows) ) );
result_GH.copyTo( canvas( Rect(img.cols*2, 0, img.cols, img.rows) ) );
/// Visualize result
imshow("Skeleton", canvas); waitKey(0);
return 0;
}

Some files were not shown because too many files have changed in this diff Show More