mirror of
https://github.com/opencv/opencv.git
synced 2026-07-31 00:03:03 +04:00
Merge remote-tracking branch 'upstream/3.4' into merge-3.4
OpenCV FFmpeg wrapper download links are preserved from ffmpeg/master branch
This commit is contained in:
+138
-26
@@ -15,55 +15,167 @@ Theory
|
||||
Code
|
||||
----
|
||||
|
||||
@add_toggle_cpp
|
||||
This tutorial code's is shown lines below. You can also download it from
|
||||
[here](https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp)
|
||||
@include samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
This tutorial code's is shown lines below. You can also download it from
|
||||
[here](https://github.com/opencv/opencv/tree/master/samples/java/tutorial_code/ShapeDescriptors/bounding_rects_circles/GeneralContoursDemo1.java)
|
||||
@include samples/java/tutorial_code/ShapeDescriptors/bounding_rects_circles/GeneralContoursDemo1.java
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
This tutorial code's is shown lines below. You can also download it from
|
||||
[here](https://github.com/opencv/opencv/tree/master/samples/python/tutorial_code/ShapeDescriptors/bounding_rects_circles/generalContours_demo1.py)
|
||||
@include samples/python/tutorial_code/ShapeDescriptors/bounding_rects_circles/generalContours_demo1.py
|
||||
@end_toggle
|
||||
|
||||
Explanation
|
||||
-----------
|
||||
|
||||
The main function is rather simple, as follows from the comments we do the following:
|
||||
-# Open the image, convert it into grayscale and blur it to get rid of the noise.
|
||||
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp setup
|
||||
-# Create a window with header "Source" and display the source file in it.
|
||||
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp createWindow
|
||||
-# Create a trackbar on the source_window and assign a callback function to it
|
||||
- Open the image, convert it into grayscale and blur it to get rid of the noise.
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp setup
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ShapeDescriptors/bounding_rects_circles/GeneralContoursDemo1.java setup
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ShapeDescriptors/bounding_rects_circles/generalContours_demo1.py setup
|
||||
@end_toggle
|
||||
|
||||
- Create a window with header "Source" and display the source file in it.
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp createWindow
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ShapeDescriptors/bounding_rects_circles/GeneralContoursDemo1.java createWindow
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ShapeDescriptors/bounding_rects_circles/generalContours_demo1.py createWindow
|
||||
@end_toggle
|
||||
|
||||
- Create a trackbar on the `source_window` and assign a callback function to it.
|
||||
In general callback functions are used to react to some kind of signal, in our
|
||||
case it's trackbar's state change.
|
||||
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp taskbar
|
||||
-# Explicit one-time call of `thresh_callback` is necessary to display
|
||||
Explicit one-time call of `thresh_callback` is necessary to display
|
||||
the "Contours" window simultaniously with the "Source" window.
|
||||
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp callback00
|
||||
-# Wait for user to close the windows.
|
||||
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp waitForIt
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp trackbar
|
||||
@end_toggle
|
||||
|
||||
The callback function `thresh_callback` does all the interesting job.
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ShapeDescriptors/bounding_rects_circles/GeneralContoursDemo1.java trackbar
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ShapeDescriptors/bounding_rects_circles/generalContours_demo1.py trackbar
|
||||
@end_toggle
|
||||
|
||||
-# Writes to `threshold_output` the threshold of the grayscale picture (you can check out about thresholding @ref tutorial_threshold "here").
|
||||
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp threshold
|
||||
-# Finds contours and saves them to the vectors `contour` and `hierarchy`.
|
||||
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp findContours
|
||||
-# For every found contour we now apply approximation to polygons
|
||||
with accuracy +-3 and stating that the curve must me closed.
|
||||
The callback function does all the interesting job.
|
||||
|
||||
- Use @ref cv::Canny to detect edges in the images.
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp Canny
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ShapeDescriptors/bounding_rects_circles/GeneralContoursDemo1.java Canny
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ShapeDescriptors/bounding_rects_circles/generalContours_demo1.py Canny
|
||||
@end_toggle
|
||||
|
||||
- Finds contours and saves them to the vectors `contour` and `hierarchy`.
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp findContours
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ShapeDescriptors/bounding_rects_circles/GeneralContoursDemo1.java findContours
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ShapeDescriptors/bounding_rects_circles/generalContours_demo1.py findContours
|
||||
@end_toggle
|
||||
|
||||
- For every found contour we now apply approximation to polygons
|
||||
with accuracy +-3 and stating that the curve must be closed.
|
||||
After that we find a bounding rect for every polygon and save it to `boundRect`.
|
||||
|
||||
At last we find a minimum enclosing circle for every polygon and
|
||||
save it to `center` and `radius` vectors.
|
||||
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp allthework
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp allthework
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ShapeDescriptors/bounding_rects_circles/GeneralContoursDemo1.java allthework
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ShapeDescriptors/bounding_rects_circles/generalContours_demo1.py allthework
|
||||
@end_toggle
|
||||
|
||||
We found everything we need, all we have to do is to draw.
|
||||
|
||||
-# Create new Mat of unsigned 8-bit chars, filled with zeros.
|
||||
- Create new Mat of unsigned 8-bit chars, filled with zeros.
|
||||
It will contain all the drawings we are going to make (rects and circles).
|
||||
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp zeroMat
|
||||
-# For every contour: pick a random color, draw the contour, the bounding rectangle and
|
||||
the minimal enclosing circle with it,
|
||||
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp forContour
|
||||
-# Display the results: create a new window "Contours" and show everything we added to drawings on it.
|
||||
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp showDrawings
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp zeroMat
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ShapeDescriptors/bounding_rects_circles/GeneralContoursDemo1.java zeroMat
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ShapeDescriptors/bounding_rects_circles/generalContours_demo1.py zeroMat
|
||||
@end_toggle
|
||||
|
||||
- For every contour: pick a random color, draw the contour, the bounding rectangle and
|
||||
the minimal enclosing circle with it.
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp forContour
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ShapeDescriptors/bounding_rects_circles/GeneralContoursDemo1.java forContour
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ShapeDescriptors/bounding_rects_circles/generalContours_demo1.py forContour
|
||||
@end_toggle
|
||||
|
||||
- Display the results: create a new window "Contours" and show everything we added to drawings on it.
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp showDrawings
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ShapeDescriptors/bounding_rects_circles/GeneralContoursDemo1.java showDrawings
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ShapeDescriptors/bounding_rects_circles/generalContours_demo1.py showDrawings
|
||||
@end_toggle
|
||||
|
||||
Result
|
||||
------
|
||||
|
||||
+14
@@ -15,9 +15,23 @@ Theory
|
||||
Code
|
||||
----
|
||||
|
||||
@add_toggle_cpp
|
||||
This tutorial code's is shown lines below. You can also download it from
|
||||
[here](https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo2.cpp)
|
||||
@include samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo2.cpp
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
This tutorial code's is shown lines below. You can also download it from
|
||||
[here](https://github.com/opencv/opencv/tree/master/samples/java/tutorial_code/ShapeDescriptors/bounding_rotated_ellipses/GeneralContoursDemo2.java)
|
||||
@include samples/java/tutorial_code/ShapeDescriptors/bounding_rotated_ellipses/GeneralContoursDemo2.java
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
This tutorial code's is shown lines below. You can also download it from
|
||||
[here](https://github.com/opencv/opencv/tree/master/samples/python/tutorial_code/ShapeDescriptors/bounding_rotated_ellipses/generalContours_demo2.py)
|
||||
@include samples/python/tutorial_code/ShapeDescriptors/bounding_rotated_ellipses/generalContours_demo2.py
|
||||
@end_toggle
|
||||
|
||||
Explanation
|
||||
-----------
|
||||
|
||||
@@ -15,9 +15,23 @@ Theory
|
||||
Code
|
||||
----
|
||||
|
||||
@add_toggle_cpp
|
||||
This tutorial code's is shown lines below. You can also download it from
|
||||
[here](https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/ShapeDescriptors/findContours_demo.cpp)
|
||||
@include samples/cpp/tutorial_code/ShapeDescriptors/findContours_demo.cpp
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
This tutorial code's is shown lines below. You can also download it from
|
||||
[here](https://github.com/opencv/opencv/tree/master/samples/java/tutorial_code/ShapeDescriptors/find_contours/FindContoursDemo.java)
|
||||
@include samples/java/tutorial_code/ShapeDescriptors/find_contours/FindContoursDemo.java
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
This tutorial code's is shown lines below. You can also download it from
|
||||
[here](https://github.com/opencv/opencv/tree/master/samples/python/tutorial_code/ShapeDescriptors/find_contours/findContours_demo.py)
|
||||
@include samples/python/tutorial_code/ShapeDescriptors/find_contours/findContours_demo.py
|
||||
@end_toggle
|
||||
|
||||
Explanation
|
||||
-----------
|
||||
|
||||
@@ -14,10 +14,23 @@ Theory
|
||||
Code
|
||||
----
|
||||
|
||||
@add_toggle_cpp
|
||||
This tutorial code's is shown lines below. You can also download it from
|
||||
[here](https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/ShapeDescriptors/hull_demo.cpp)
|
||||
|
||||
@include samples/cpp/tutorial_code/ShapeDescriptors/hull_demo.cpp
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
This tutorial code's is shown lines below. You can also download it from
|
||||
[here](https://github.com/opencv/opencv/tree/master/samples/java/tutorial_code/ShapeDescriptors/hull/HullDemo.java)
|
||||
@include samples/java/tutorial_code/ShapeDescriptors/hull/HullDemo.java
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
This tutorial code's is shown lines below. You can also download it from
|
||||
[here](https://github.com/opencv/opencv/tree/master/samples/python/tutorial_code/ShapeDescriptors/hull/hull_demo.py)
|
||||
@include samples/python/tutorial_code/ShapeDescriptors/hull/hull_demo.py
|
||||
@end_toggle
|
||||
|
||||
Explanation
|
||||
-----------
|
||||
|
||||
@@ -16,9 +16,23 @@ Theory
|
||||
Code
|
||||
----
|
||||
|
||||
@add_toggle_cpp
|
||||
This tutorial code's is shown lines below. You can also download it from
|
||||
[here](https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/ShapeDescriptors/moments_demo.cpp)
|
||||
@include samples/cpp/tutorial_code/ShapeDescriptors/moments_demo.cpp
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
This tutorial code's is shown lines below. You can also download it from
|
||||
[here](https://github.com/opencv/opencv/tree/master/samples/java/tutorial_code/ShapeDescriptors/moments/MomentsDemo.java)
|
||||
@include samples/java/tutorial_code/ShapeDescriptors/moments/MomentsDemo.java
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
This tutorial code's is shown lines below. You can also download it from
|
||||
[here](https://github.com/opencv/opencv/tree/master/samples/python/tutorial_code/ShapeDescriptors/moments/moments_demo.py)
|
||||
@include samples/python/tutorial_code/ShapeDescriptors/moments/moments_demo.py
|
||||
@end_toggle
|
||||
|
||||
Explanation
|
||||
-----------
|
||||
|
||||
@@ -14,9 +14,23 @@ Theory
|
||||
Code
|
||||
----
|
||||
|
||||
@add_toggle_cpp
|
||||
This tutorial code's is shown lines below. You can also download it from
|
||||
[here](https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/ShapeDescriptors/pointPolygonTest_demo.cpp)
|
||||
@include samples/cpp/tutorial_code/ShapeDescriptors/pointPolygonTest_demo.cpp
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
This tutorial code's is shown lines below. You can also download it from
|
||||
[here](https://github.com/opencv/opencv/tree/master/samples/java/tutorial_code/ShapeDescriptors/point_polygon_test/PointPolygonTestDemo.java)
|
||||
@include samples/java/tutorial_code/ShapeDescriptors/point_polygon_test/PointPolygonTestDemo.java
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
This tutorial code's is shown lines below. You can also download it from
|
||||
[here](https://github.com/opencv/opencv/tree/master/samples/python/tutorial_code/ShapeDescriptors/point_polygon_test/pointPolygonTest_demo.py)
|
||||
@include samples/python/tutorial_code/ShapeDescriptors/point_polygon_test/pointPolygonTest_demo.py
|
||||
@end_toggle
|
||||
|
||||
Explanation
|
||||
-----------
|
||||
|
||||
@@ -225,6 +225,8 @@ In this section you will learn about the image processing (manipulation) functio
|
||||
|
||||
- @subpage tutorial_find_contours
|
||||
|
||||
*Languages:* C++, Java, Python
|
||||
|
||||
*Compatibility:* \> OpenCV 2.0
|
||||
|
||||
*Author:* Ana Huamán
|
||||
@@ -233,6 +235,8 @@ In this section you will learn about the image processing (manipulation) functio
|
||||
|
||||
- @subpage tutorial_hull
|
||||
|
||||
*Languages:* C++, Java, Python
|
||||
|
||||
*Compatibility:* \> OpenCV 2.0
|
||||
|
||||
*Author:* Ana Huamán
|
||||
@@ -241,6 +245,8 @@ In this section you will learn about the image processing (manipulation) functio
|
||||
|
||||
- @subpage tutorial_bounding_rects_circles
|
||||
|
||||
*Languages:* C++, Java, Python
|
||||
|
||||
*Compatibility:* \> OpenCV 2.0
|
||||
|
||||
*Author:* Ana Huamán
|
||||
@@ -249,6 +255,8 @@ In this section you will learn about the image processing (manipulation) functio
|
||||
|
||||
- @subpage tutorial_bounding_rotated_ellipses
|
||||
|
||||
*Languages:* C++, Java, Python
|
||||
|
||||
*Compatibility:* \> OpenCV 2.0
|
||||
|
||||
*Author:* Ana Huamán
|
||||
@@ -257,6 +265,8 @@ In this section you will learn about the image processing (manipulation) functio
|
||||
|
||||
- @subpage tutorial_moments
|
||||
|
||||
*Languages:* C++, Java, Python
|
||||
|
||||
*Compatibility:* \> OpenCV 2.0
|
||||
|
||||
*Author:* Ana Huamán
|
||||
@@ -265,6 +275,8 @@ In this section you will learn about the image processing (manipulation) functio
|
||||
|
||||
- @subpage tutorial_point_polygon_test
|
||||
|
||||
*Languages:* C++, Java, Python
|
||||
|
||||
*Compatibility:* \> OpenCV 2.0
|
||||
|
||||
*Author:* Ana Huamán
|
||||
|
||||
@@ -86,3 +86,16 @@ When you run the code you should see 3x3 identity matrix as output.
|
||||
|
||||
That is it, whenever you start a new project just add the OpenCV user library that you have defined
|
||||
to your project and you are good to go. Enjoy your powerful, less painful development environment :)
|
||||
|
||||
Running Java code with OpenCV and MKL dependency
|
||||
------------------------------------------------
|
||||
|
||||
You may get the following error (e.g. on Ubuntu) if you have built OpenCV with MKL library with some Java code that calls OpenCV functions
|
||||
that use Intel MKL:
|
||||
> Intel MKL FATAL ERROR: Cannot load libmkl_avx2.so or libmkl_def.so.
|
||||
|
||||
One solution to solve this on Linux consists in preloading the Intel MKL library (either run the command in a terminal or add it to your `.bashrc` file).
|
||||
Your command line should be something similar to this (add `$LD_PRELOAD:` before if you have already set the `LD_PRELOAD` variable):
|
||||
> export LD_PRELOAD=/opt/intel/mkl/lib/intel64/libmkl_core.so:/opt/intel/mkl/lib/intel64/libmkl_sequential.so
|
||||
|
||||
Then, run the Eclipse IDE from a terminal that have this environment variable set (`echo $LD_PRELOAD`) and the error should disappear.
|
||||
|
||||
@@ -17,9 +17,23 @@ Theory
|
||||
Code
|
||||
----
|
||||
|
||||
@add_toggle_cpp
|
||||
This tutorial code's is shown lines below. You can also download it from
|
||||
[here](https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/objectDetection/objectDetection.cpp)
|
||||
@include samples/cpp/tutorial_code/objectDetection/objectDetection.cpp
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
This tutorial code's is shown lines below. You can also download it from
|
||||
[here](https://github.com/opencv/opencv/tree/master/samples/java/tutorial_code/objectDetection/cascade_classifier/ObjectDetectionDemo.java)
|
||||
@include samples/java/tutorial_code/objectDetection/cascade_classifier/ObjectDetectionDemo.java
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
This tutorial code's is shown lines below. You can also download it from
|
||||
[here](https://github.com/opencv/opencv/tree/master/samples/python/tutorial_code/objectDetection/cascade_classifier/objectDetection.py)
|
||||
@include samples/python/tutorial_code/objectDetection/cascade_classifier/objectDetection.py
|
||||
@end_toggle
|
||||
|
||||
Explanation
|
||||
-----------
|
||||
@@ -40,3 +54,13 @@ Result
|
||||
detection. For the eyes we keep using the file used in the tutorial.
|
||||
|
||||

|
||||
|
||||
Additional Resources
|
||||
--------------------
|
||||
|
||||
-# Paul Viola and Michael J. Jones. Robust real-time face detection. International Journal of Computer Vision, 57(2):137–154, 2004. @cite Viola04
|
||||
-# Rainer Lienhart and Jochen Maydt. An extended set of haar-like features for rapid object detection. In Image Processing. 2002. Proceedings. 2002 International Conference on, volume 1, pages I–900. IEEE, 2002. @cite Lienhart02
|
||||
-# Video Lecture on [Face Detection and Tracking](https://www.youtube.com/watch?v=WfdYYNamHZ8)
|
||||
-# An interesting interview regarding Face Detection by [Adam
|
||||
Harvey](https://web.archive.org/web/20171204220159/http://www.makematics.com/research/viola-jones/)
|
||||
-# [OpenCV Face Detection: Visualized](https://vimeo.com/12774628) on Vimeo by Adam Harvey
|
||||
|
||||
@@ -5,6 +5,8 @@ Ever wondered how your digital camera detects peoples and faces? Look here to fi
|
||||
|
||||
- @subpage tutorial_cascade_classifier
|
||||
|
||||
*Languages:* C++, Java, Python
|
||||
|
||||
*Compatibility:* \> OpenCV 2.0
|
||||
|
||||
*Author:* Ana Huamán
|
||||
|
||||
@@ -31,21 +31,51 @@ Exposure sequence
|
||||
Source Code
|
||||
-----------
|
||||
|
||||
@include cpp/tutorial_code/photo/hdr_imaging/hdr_imaging.cpp
|
||||
@add_toggle_cpp
|
||||
This tutorial code's is shown lines below. You can also download it from
|
||||
[here](https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/photo/hdr_imaging/hdr_imaging.cpp)
|
||||
@include samples/cpp/tutorial_code/photo/hdr_imaging/hdr_imaging.cpp
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
This tutorial code's is shown lines below. You can also download it from
|
||||
[here](https://github.com/opencv/opencv/tree/master/samples/java/tutorial_code/photo/hdr_imaging/HDRImagingDemo.java)
|
||||
@include samples/java/tutorial_code/photo/hdr_imaging/HDRImagingDemo.java
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
This tutorial code's is shown lines below. You can also download it from
|
||||
[here](https://github.com/opencv/opencv/tree/master/samples/python/tutorial_code/photo/hdr_imaging/hdr_imaging.py)
|
||||
@include samples/python/tutorial_code/photo/hdr_imaging/hdr_imaging.py
|
||||
@end_toggle
|
||||
|
||||
Sample images
|
||||
-------------
|
||||
|
||||
Data directory that contains images, exposure times and `list.txt` file can be downloaded from
|
||||
[here](https://github.com/opencv/opencv_extra/tree/master/testdata/cv/hdr/exposures).
|
||||
|
||||
Explanation
|
||||
-----------
|
||||
|
||||
-# **Load images and exposure times**
|
||||
@code{.cpp}
|
||||
vector<Mat> images;
|
||||
vector<float> times;
|
||||
loadExposureSeq(argv[1], images, times);
|
||||
@endcode
|
||||
Firstly we load input images and exposure times from user-defined folder. The folder should
|
||||
contain images and *list.txt* - file that contains file names and inverse exposure times.
|
||||
- **Load images and exposure times**
|
||||
|
||||
For our image sequence the list is following:
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/photo/hdr_imaging/hdr_imaging.cpp Load images and exposure times
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/photo/hdr_imaging/HDRImagingDemo.java Load images and exposure times
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/photo/hdr_imaging/hdr_imaging.py Load images and exposure times
|
||||
@end_toggle
|
||||
|
||||
Firstly we load input images and exposure times from user-defined folder. The folder should
|
||||
contain images and *list.txt* - file that contains file names and inverse exposure times.
|
||||
|
||||
For our image sequence the list is following:
|
||||
@code{.none}
|
||||
memorial00.png 0.03125
|
||||
memorial01.png 0.0625
|
||||
@@ -53,53 +83,96 @@ Explanation
|
||||
memorial15.png 1024
|
||||
@endcode
|
||||
|
||||
-# **Estimate camera response**
|
||||
@code{.cpp}
|
||||
Mat response;
|
||||
Ptr<CalibrateDebevec> calibrate = createCalibrateDebevec();
|
||||
calibrate->process(images, response, times);
|
||||
@endcode
|
||||
It is necessary to know camera response function (CRF) for a lot of HDR construction algorithms.
|
||||
We use one of the calibration algorithms to estimate inverse CRF for all 256 pixel values.
|
||||
- **Estimate camera response**
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/photo/hdr_imaging/hdr_imaging.cpp Estimate camera response
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/photo/hdr_imaging/HDRImagingDemo.java Estimate camera response
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/photo/hdr_imaging/hdr_imaging.py Estimate camera response
|
||||
@end_toggle
|
||||
|
||||
It is necessary to know camera response function (CRF) for a lot of HDR construction algorithms.
|
||||
We use one of the calibration algorithms to estimate inverse CRF for all 256 pixel values.
|
||||
|
||||
- **Make HDR image**
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/photo/hdr_imaging/hdr_imaging.cpp Make HDR image
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/photo/hdr_imaging/HDRImagingDemo.java Make HDR image
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/photo/hdr_imaging/hdr_imaging.py Make HDR image
|
||||
@end_toggle
|
||||
|
||||
-# **Make HDR image**
|
||||
@code{.cpp}
|
||||
Mat hdr;
|
||||
Ptr<MergeDebevec> merge_debevec = createMergeDebevec();
|
||||
merge_debevec->process(images, hdr, times, response);
|
||||
@endcode
|
||||
We use Debevec's weighting scheme to construct HDR image using response calculated in the previous
|
||||
item.
|
||||
|
||||
-# **Tonemap HDR image**
|
||||
@code{.cpp}
|
||||
Mat ldr;
|
||||
Ptr<TonemapDurand> tonemap = createTonemapDurand(2.2f);
|
||||
tonemap->process(hdr, ldr);
|
||||
@endcode
|
||||
Since we want to see our results on common LDR display we have to map our HDR image to 8-bit range
|
||||
preserving most details. It is the main goal of tonemapping methods. We use tonemapper with
|
||||
bilateral filtering and set 2.2 as the value for gamma correction.
|
||||
- **Tonemap HDR image**
|
||||
|
||||
-# **Perform exposure fusion**
|
||||
@code{.cpp}
|
||||
Mat fusion;
|
||||
Ptr<MergeMertens> merge_mertens = createMergeMertens();
|
||||
merge_mertens->process(images, fusion);
|
||||
@endcode
|
||||
There is an alternative way to merge our exposures in case when we don't need HDR image. This
|
||||
process is called exposure fusion and produces LDR image that doesn't require gamma correction. It
|
||||
also doesn't use exposure values of the photographs.
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/photo/hdr_imaging/hdr_imaging.cpp Tonemap HDR image
|
||||
@end_toggle
|
||||
|
||||
-# **Write results**
|
||||
@code{.cpp}
|
||||
imwrite("fusion.png", fusion * 255);
|
||||
imwrite("ldr.png", ldr * 255);
|
||||
imwrite("hdr.hdr", hdr);
|
||||
@endcode
|
||||
Now it's time to look at the results. Note that HDR image can't be stored in one of common image
|
||||
formats, so we save it to Radiance image (.hdr). Also all HDR imaging functions return results in
|
||||
[0, 1] range so we should multiply result by 255.
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/photo/hdr_imaging/HDRImagingDemo.java Tonemap HDR image
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/photo/hdr_imaging/hdr_imaging.py Tonemap HDR image
|
||||
@end_toggle
|
||||
|
||||
Since we want to see our results on common LDR display we have to map our HDR image to 8-bit range
|
||||
preserving most details. It is the main goal of tonemapping methods. We use tonemapper with
|
||||
bilateral filtering and set 2.2 as the value for gamma correction.
|
||||
|
||||
- **Perform exposure fusion**
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/photo/hdr_imaging/hdr_imaging.cpp Perform exposure fusion
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/photo/hdr_imaging/HDRImagingDemo.java Perform exposure fusion
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/photo/hdr_imaging/hdr_imaging.py Perform exposure fusion
|
||||
@end_toggle
|
||||
|
||||
There is an alternative way to merge our exposures in case when we don't need HDR image. This
|
||||
process is called exposure fusion and produces LDR image that doesn't require gamma correction. It
|
||||
also doesn't use exposure values of the photographs.
|
||||
|
||||
- **Write results**
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/photo/hdr_imaging/hdr_imaging.cpp Write results
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/photo/hdr_imaging/HDRImagingDemo.java Write results
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/photo/hdr_imaging/hdr_imaging.py Write results
|
||||
@end_toggle
|
||||
|
||||
Now it's time to look at the results. Note that HDR image can't be stored in one of common image
|
||||
formats, so we save it to Radiance image (.hdr). Also all HDR imaging functions return results in
|
||||
[0, 1] range so we should multiply result by 255.
|
||||
|
||||
You can try other tonemap algorithms: cv::TonemapDrago, cv::TonemapDurand, cv::TonemapMantiuk and cv::TonemapReinhard
|
||||
You can also adjust the parameters in the HDR calibration and tonemap methods for your own photos.
|
||||
|
||||
Results
|
||||
-------
|
||||
@@ -111,3 +184,12 @@ Results
|
||||
### Exposure fusion
|
||||
|
||||

|
||||
|
||||
Additional Resources
|
||||
--------------------
|
||||
|
||||
1. Paul E Debevec and Jitendra Malik. Recovering high dynamic range radiance maps from photographs. In ACM SIGGRAPH 2008 classes, page 31. ACM, 2008. @cite DM97
|
||||
2. Mark A Robertson, Sean Borman, and Robert L Stevenson. Dynamic range improvement through multiple exposures. In Image Processing, 1999. ICIP 99. Proceedings. 1999 International Conference on, volume 3, pages 159–163. IEEE, 1999. @cite RB99
|
||||
3. Tom Mertens, Jan Kautz, and Frank Van Reeth. Exposure fusion. In Computer Graphics and Applications, 2007. PG'07. 15th Pacific Conference on, pages 382–390. IEEE, 2007. @cite MK07
|
||||
4. [Wikipedia-HDR](https://en.wikipedia.org/wiki/High-dynamic-range_imaging)
|
||||
5. [Recovering High Dynamic Range Radiance Maps from Photographs (webpage)](http://www.pauldebevec.com/Research/HDR/)
|
||||
|
||||
@@ -5,6 +5,8 @@ Use OpenCV for advanced photo processing.
|
||||
|
||||
- @subpage tutorial_hdr_imaging
|
||||
|
||||
*Languages:* C++, Java, Python
|
||||
|
||||
*Compatibility:* \> OpenCV 3.0
|
||||
|
||||
*Author:* Fedor Morozov
|
||||
|
||||
Reference in New Issue
Block a user