mirror of
https://github.com/opencv/opencv.git
synced 2024-11-30 14:29:49 +08:00
Merge pull request #12894 from alalek:c_api_drop_samples
This commit is contained in:
commit
e959f449ae
@ -2,7 +2,7 @@ File Input and Output using XML and YAML files {#tutorial_file_input_output_with
|
|||||||
==============================================
|
==============================================
|
||||||
|
|
||||||
@prev_tutorial{tutorial_discrete_fourier_transform}
|
@prev_tutorial{tutorial_discrete_fourier_transform}
|
||||||
@next_tutorial{tutorial_interoperability_with_OpenCV_1}
|
@next_tutorial{tutorial_how_to_use_OpenCV_parallel_for_}
|
||||||
|
|
||||||
Goal
|
Goal
|
||||||
----
|
----
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
How to use the OpenCV parallel_for_ to parallelize your code {#tutorial_how_to_use_OpenCV_parallel_for_}
|
How to use the OpenCV parallel_for_ to parallelize your code {#tutorial_how_to_use_OpenCV_parallel_for_}
|
||||||
==================================================================
|
==================================================================
|
||||||
|
|
||||||
@prev_tutorial{tutorial_interoperability_with_OpenCV_1}
|
@prev_tutorial{tutorial_file_input_output_with_xml_yml}
|
||||||
|
|
||||||
Goal
|
Goal
|
||||||
----
|
----
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 25 KiB |
@ -1,143 +0,0 @@
|
|||||||
Interoperability with OpenCV 1 {#tutorial_interoperability_with_OpenCV_1}
|
|
||||||
==============================
|
|
||||||
|
|
||||||
@prev_tutorial{tutorial_file_input_output_with_xml_yml}
|
|
||||||
@next_tutorial{tutorial_how_to_use_OpenCV_parallel_for_}
|
|
||||||
|
|
||||||
Goal
|
|
||||||
----
|
|
||||||
|
|
||||||
For the OpenCV developer team it's important to constantly improve the library. We are constantly
|
|
||||||
thinking about methods that will ease your work process, while still maintain the libraries
|
|
||||||
flexibility. The new C++ interface is a development of us that serves this goal. Nevertheless,
|
|
||||||
backward compatibility remains important. We do not want to break your code written for earlier
|
|
||||||
version of the OpenCV library. Therefore, we made sure that we add some functions that deal with
|
|
||||||
this. In the following you'll learn:
|
|
||||||
|
|
||||||
- What changed with the version 2 of OpenCV in the way you use the library compared to its first
|
|
||||||
version
|
|
||||||
- How to add some Gaussian noise to an image
|
|
||||||
- What are lookup tables and why use them?
|
|
||||||
|
|
||||||
General
|
|
||||||
-------
|
|
||||||
|
|
||||||
When making the switch you first need to learn some about the new data structure for images:
|
|
||||||
@ref tutorial_mat_the_basic_image_container, this replaces the old *CvMat* and *IplImage* ones. Switching to the new
|
|
||||||
functions is easier. You just need to remember a couple of new things.
|
|
||||||
|
|
||||||
OpenCV 2 received reorganization. No longer are all the functions crammed into a single library. We
|
|
||||||
have many modules, each of them containing data structures and functions relevant to certain tasks.
|
|
||||||
This way you do not need to ship a large library if you use just a subset of OpenCV. This means that
|
|
||||||
you should also include only those headers you will use. For example:
|
|
||||||
@code{.cpp}
|
|
||||||
#include <opencv2/core.hpp>
|
|
||||||
#include <opencv2/imgproc.hpp>
|
|
||||||
#include <opencv2/highgui.hpp>
|
|
||||||
@endcode
|
|
||||||
All the OpenCV related stuff is put into the *cv* namespace to avoid name conflicts with other
|
|
||||||
libraries data structures and functions. Therefore, either you need to prepend the *cv::* keyword
|
|
||||||
before everything that comes from OpenCV or after the includes, you just add a directive to use
|
|
||||||
this:
|
|
||||||
@code{.cpp}
|
|
||||||
using namespace cv; // The new C++ interface API is inside this namespace. Import it.
|
|
||||||
@endcode
|
|
||||||
Because the functions are already in a namespace there is no need for them to contain the *cv*
|
|
||||||
prefix in their name. As such all the new C++ compatible functions don't have this and they follow
|
|
||||||
the camel case naming rule. This means the first letter is small (unless it's a name, like Canny)
|
|
||||||
and the subsequent words start with a capital letter (like *copyMakeBorder*).
|
|
||||||
|
|
||||||
Now, remember that you need to link to your application all the modules you use, and in case you are
|
|
||||||
on Windows using the *DLL* system you will need to add, again, to the path all the binaries. For
|
|
||||||
more in-depth information if you're on Windows read @ref tutorial_windows_visual_studio_opencv and for
|
|
||||||
Linux an example usage is explained in @ref tutorial_linux_eclipse.
|
|
||||||
|
|
||||||
Now for converting the *Mat* object you can use either the *IplImage* or the *CvMat* operators.
|
|
||||||
While in the C interface you used to work with pointers here it's no longer the case. In the C++
|
|
||||||
interface we have mostly *Mat* objects. These objects may be freely converted to both *IplImage* and
|
|
||||||
*CvMat* with simple assignment. For example:
|
|
||||||
@code{.cpp}
|
|
||||||
Mat I;
|
|
||||||
IplImage pI = I;
|
|
||||||
CvMat mI = I;
|
|
||||||
@endcode
|
|
||||||
Now if you want pointers the conversion gets just a little more complicated. The compilers can no
|
|
||||||
longer automatically determinate what you want and as you need to explicitly specify your goal. This
|
|
||||||
is to call the *IplImage* and *CvMat* operators and then get their pointers. For getting the pointer
|
|
||||||
we use the & sign:
|
|
||||||
@code{.cpp}
|
|
||||||
Mat I;
|
|
||||||
IplImage* pI = &I.operator IplImage();
|
|
||||||
CvMat* mI = &I.operator CvMat();
|
|
||||||
@endcode
|
|
||||||
One of the biggest complaints of the C interface is that it leaves all the memory management to you.
|
|
||||||
You need to figure out when it is safe to release your unused objects and make sure you do so before
|
|
||||||
the program finishes or you could have troublesome memory leaks. To work around this issue in OpenCV
|
|
||||||
there is introduced a sort of smart pointer. This will automatically release the object when it's no
|
|
||||||
longer in use. To use this declare the pointers as a specialization of the *Ptr* :
|
|
||||||
@code{.cpp}
|
|
||||||
Ptr<IplImage> piI = &I.operator IplImage();
|
|
||||||
@endcode
|
|
||||||
Converting from the C data structures to the *Mat* is done by passing these inside its constructor.
|
|
||||||
For example:
|
|
||||||
@code{.cpp}
|
|
||||||
Mat K(piL), L;
|
|
||||||
L = Mat(pI);
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
A case study
|
|
||||||
------------
|
|
||||||
|
|
||||||
Now that you have the basics done [here's](https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/core/interoperability_with_OpenCV_1/interoperability_with_OpenCV_1.cpp)
|
|
||||||
an example that mixes the usage of the C interface with the C++ one. You will also find it in the
|
|
||||||
sample directory of the OpenCV source code library at the
|
|
||||||
`samples/cpp/tutorial_code/core/interoperability_with_OpenCV_1/interoperability_with_OpenCV_1.cpp` .
|
|
||||||
To further help on seeing the difference the programs supports two modes: one mixed C and C++ and
|
|
||||||
one pure C++. If you define the *DEMO_MIXED_API_USE* you'll end up using the first. The program
|
|
||||||
separates the color planes, does some modifications on them and in the end merge them back together.
|
|
||||||
|
|
||||||
@snippet interoperability_with_OpenCV_1.cpp head
|
|
||||||
@snippet interoperability_with_OpenCV_1.cpp start
|
|
||||||
|
|
||||||
Here you can observe that with the new structure we have no pointer problems, although it is
|
|
||||||
possible to use the old functions and in the end just transform the result to a *Mat* object.
|
|
||||||
|
|
||||||
@snippet interoperability_with_OpenCV_1.cpp new
|
|
||||||
|
|
||||||
Because, we want to mess around with the images luma component we first convert from the default BGR
|
|
||||||
to the YUV color space and then split the result up into separate planes. Here the program splits:
|
|
||||||
in the first example it processes each plane using one of the three major image scanning algorithms
|
|
||||||
in OpenCV (C [] operator, iterator, individual element access). In a second variant we add to the
|
|
||||||
image some Gaussian noise and then mix together the channels according to some formula.
|
|
||||||
|
|
||||||
The scanning version looks like:
|
|
||||||
|
|
||||||
@snippet interoperability_with_OpenCV_1.cpp scanning
|
|
||||||
|
|
||||||
Here you can observe that we may go through all the pixels of an image in three fashions: an
|
|
||||||
iterator, a C pointer and an individual element access style. You can read a more in-depth
|
|
||||||
description of these in the @ref tutorial_how_to_scan_images tutorial. Converting from the old function
|
|
||||||
names is easy. Just remove the cv prefix and use the new *Mat* data structure. Here's an example of
|
|
||||||
this by using the weighted addition function:
|
|
||||||
|
|
||||||
@snippet interoperability_with_OpenCV_1.cpp noisy
|
|
||||||
|
|
||||||
As you may observe the *planes* variable is of type *Mat*. However, converting from *Mat* to
|
|
||||||
*IplImage* is easy and made automatically with a simple assignment operator.
|
|
||||||
|
|
||||||
@snippet interoperability_with_OpenCV_1.cpp end
|
|
||||||
|
|
||||||
The new *imshow* highgui function accepts both the *Mat* and *IplImage* data structures. Compile and
|
|
||||||
run the program and if the first image below is your input you may get either the first or second as
|
|
||||||
output:
|
|
||||||
|
|
||||||
![](images/outputInteropOpenCV1.jpg)
|
|
||||||
|
|
||||||
You may observe a runtime instance of this on the [YouTube
|
|
||||||
here](https://www.youtube.com/watch?v=qckm-zvo31w) and you can [download the source code from here
|
|
||||||
](https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/core/interoperability_with_OpenCV_1/interoperability_with_OpenCV_1.cpp)
|
|
||||||
or find it in the
|
|
||||||
`samples/cpp/tutorial_code/core/interoperability_with_OpenCV_1/interoperability_with_OpenCV_1.cpp`
|
|
||||||
of the OpenCV source code library.
|
|
||||||
|
|
||||||
@youtube{qckm-zvo31w}
|
|
@ -150,11 +150,12 @@ If we need to copy the data, this is done using, for example, cv::Mat::copyTo or
|
|||||||
@snippet samples/python/tutorial_code/core/mat_operations/mat_operations.py Reference counting 2
|
@snippet samples/python/tutorial_code/core/mat_operations/mat_operations.py Reference counting 2
|
||||||
@end_toggle
|
@end_toggle
|
||||||
|
|
||||||
To the contrary with C API where an output image had to be created by the developer, an empty output Mat
|
An empty output Mat can be supplied to each function.
|
||||||
can be supplied to each function. Each implementation calls Mat::create for a destination matrix.
|
Each implementation calls Mat::create for a destination matrix.
|
||||||
This method allocates data for a matrix if it is empty. If it is not empty and has the correct size
|
This method allocates data for a matrix if it is empty.
|
||||||
and type, the method does nothing. If however, size or type are different from the input arguments, the
|
If it is not empty and has the correct size and type, the method does nothing.
|
||||||
data is deallocated (and lost) and a new data is allocated. For example:
|
If however, size or type are different from the input arguments, the data is deallocated (and lost) and a new data is allocated.
|
||||||
|
For example:
|
||||||
|
|
||||||
@add_toggle_cpp
|
@add_toggle_cpp
|
||||||
@snippet samples/cpp/tutorial_code/core/mat_operations/mat_operations.cpp Reference counting 3
|
@snippet samples/cpp/tutorial_code/core/mat_operations/mat_operations.cpp Reference counting 3
|
||||||
@ -199,12 +200,6 @@ Selecting a region of interest:
|
|||||||
@snippet samples/python/tutorial_code/core/mat_operations/mat_operations.py Select ROI
|
@snippet samples/python/tutorial_code/core/mat_operations/mat_operations.py Select ROI
|
||||||
@end_toggle
|
@end_toggle
|
||||||
|
|
||||||
A conversion from Mat to C API data structures (**C++ only**):
|
|
||||||
|
|
||||||
@snippet samples/cpp/tutorial_code/core/mat_operations/mat_operations.cpp C-API conversion
|
|
||||||
|
|
||||||
Note that there is no data copying here.
|
|
||||||
|
|
||||||
Conversion from color to greyscale:
|
Conversion from color to greyscale:
|
||||||
|
|
||||||
@add_toggle_cpp
|
@add_toggle_cpp
|
||||||
|
@ -82,17 +82,6 @@ understanding how to manipulate the images on a pixel level.
|
|||||||
You will see how to use the @ref cv::FileStorage data structure of OpenCV to write and read
|
You will see how to use the @ref cv::FileStorage data structure of OpenCV to write and read
|
||||||
data to XML or YAML file format.
|
data to XML or YAML file format.
|
||||||
|
|
||||||
- @subpage tutorial_interoperability_with_OpenCV_1
|
|
||||||
|
|
||||||
*Compatibility:* \> OpenCV 2.0
|
|
||||||
|
|
||||||
*Author:* Bernát Gábor
|
|
||||||
|
|
||||||
Did you used OpenCV before its 2.0 version? Do you wanna know what happened with your library
|
|
||||||
with 2.0? Don't you know how to convert your old OpenCV programs to the new C++ interface?
|
|
||||||
Look here to shed light on all this questions.
|
|
||||||
|
|
||||||
|
|
||||||
- @subpage tutorial_how_to_use_OpenCV_parallel_for_
|
- @subpage tutorial_how_to_use_OpenCV_parallel_for_
|
||||||
|
|
||||||
*Compatibility:* \>= OpenCV 2.4.3
|
*Compatibility:* \>= OpenCV 2.4.3
|
||||||
|
@ -62,8 +62,6 @@ Changes intended to ease the migration have been made in OpenCV 3.0, thus the fo
|
|||||||
#include "opencv2/<module>.hpp"
|
#include "opencv2/<module>.hpp"
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
2. If your code is using C API (`cv*` functions, `Cv*` structures or `CV_*` enumerations), include corresponding `*_c.h` headers. Although it is recommended to use C++ API, most of C-functions are still accessible in separate header files (opencv2/core/core_c.h, opencv2/core/types_c.h, opencv2/imgproc/imgproc_c.h, etc.).
|
|
||||||
|
|
||||||
Modern way to use algorithm {#tutorial_transition_algorithm}
|
Modern way to use algorithm {#tutorial_transition_algorithm}
|
||||||
---------------------------
|
---------------------------
|
||||||
1. Algorithm instances must be created with cv::makePtr function or corresponding static factory method if available:
|
1. Algorithm instances must be created with cv::makePtr function or corresponding static factory method if available:
|
||||||
|
@ -614,12 +614,11 @@ Note that `M.step[i] >= M.step[i+1]` (in fact, `M.step[i] >= M.step[i+1]*M.size[
|
|||||||
that 2-dimensional matrices are stored row-by-row, 3-dimensional matrices are stored plane-by-plane,
|
that 2-dimensional matrices are stored row-by-row, 3-dimensional matrices are stored plane-by-plane,
|
||||||
and so on. M.step[M.dims-1] is minimal and always equal to the element size M.elemSize() .
|
and so on. M.step[M.dims-1] is minimal and always equal to the element size M.elemSize() .
|
||||||
|
|
||||||
So, the data layout in Mat is fully compatible with CvMat, IplImage, and CvMatND types from OpenCV
|
So, the data layout in Mat is compatible with the majority of dense array types from the standard
|
||||||
1.x. It is also compatible with the majority of dense array types from the standard toolkits and
|
toolkits and SDKs, such as Numpy (ndarray), Win32 (independent device bitmaps), and others,
|
||||||
SDKs, such as Numpy (ndarray), Win32 (independent device bitmaps), and others, that is, with any
|
that is, with any array that uses *steps* (or *strides*) to compute the position of a pixel.
|
||||||
array that uses *steps* (or *strides*) to compute the position of a pixel. Due to this
|
Due to this compatibility, it is possible to make a Mat header for user-allocated data and process
|
||||||
compatibility, it is possible to make a Mat header for user-allocated data and process it in-place
|
it in-place using OpenCV functions.
|
||||||
using OpenCV functions.
|
|
||||||
|
|
||||||
There are many different ways to create a Mat object. The most popular options are listed below:
|
There are many different ways to create a Mat object. The most popular options are listed below:
|
||||||
|
|
||||||
@ -704,10 +703,6 @@ sub-matrices.
|
|||||||
Mat M = Mat(3, 3, CV_64F, m).inv();
|
Mat M = Mat(3, 3, CV_64F, m).inv();
|
||||||
@endcode
|
@endcode
|
||||||
.
|
.
|
||||||
Partial yet very common cases of this *user-allocated data* case are conversions from CvMat and
|
|
||||||
IplImage to Mat. For this purpose, there is function cv::cvarrToMat taking pointers to CvMat or
|
|
||||||
IplImage and the optional flag indicating whether to copy the data or not.
|
|
||||||
@snippet samples/cpp/image.cpp iplimage
|
|
||||||
|
|
||||||
- Use MATLAB-style array initializers, zeros(), ones(), eye(), for example:
|
- Use MATLAB-style array initializers, zeros(), ones(), eye(), for example:
|
||||||
@code
|
@code
|
||||||
@ -1641,13 +1636,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
Mat operator()(const std::vector<Range>& ranges) const;
|
Mat operator()(const std::vector<Range>& ranges) const;
|
||||||
|
|
||||||
// //! converts header to CvMat; no data is copied
|
|
||||||
// operator CvMat() const;
|
|
||||||
// //! converts header to CvMatND; no data is copied
|
|
||||||
// operator CvMatND() const;
|
|
||||||
// //! converts header to IplImage; no data is copied
|
|
||||||
// operator IplImage() const;
|
|
||||||
|
|
||||||
template<typename _Tp> operator std::vector<_Tp>() const;
|
template<typename _Tp> operator std::vector<_Tp>() const;
|
||||||
template<typename _Tp, int n> operator Vec<_Tp, n>() const;
|
template<typename _Tp, int n> operator Vec<_Tp, n>() const;
|
||||||
template<typename _Tp, int m, int n> operator Matx<_Tp, m, n>() const;
|
template<typename _Tp, int m, int n> operator Matx<_Tp, m, n>() const;
|
||||||
|
@ -1,135 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include <iostream>
|
|
||||||
#include <opencv2/imgproc.hpp>
|
|
||||||
#include <opencv2/highgui.hpp>
|
|
||||||
#include <opencv2/core/utility.hpp>
|
|
||||||
|
|
||||||
using namespace cv; // all the new API is put into "cv" namespace. Export its content
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
static void help()
|
|
||||||
{
|
|
||||||
cout <<
|
|
||||||
"\nThis program shows how to use cv::Mat and IplImages converting back and forth.\n"
|
|
||||||
"It shows reading of images, converting to planes and merging back, color conversion\n"
|
|
||||||
"and also iterating through pixels.\n"
|
|
||||||
"Call:\n"
|
|
||||||
"./image [image-name Default: ../data/lena.jpg]\n" << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
// enable/disable use of mixed API in the code below.
|
|
||||||
#define DEMO_MIXED_API_USE 1
|
|
||||||
|
|
||||||
#ifdef DEMO_MIXED_API_USE
|
|
||||||
# include <opencv2/highgui/highgui_c.h>
|
|
||||||
# include <opencv2/imgcodecs/imgcodecs_c.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int main( int argc, char** argv )
|
|
||||||
{
|
|
||||||
cv::CommandLineParser parser(argc, argv, "{help h | |}{@image|../data/lena.jpg|}");
|
|
||||||
if (parser.has("help"))
|
|
||||||
{
|
|
||||||
help();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
string imagename = parser.get<string>("@image");
|
|
||||||
#if DEMO_MIXED_API_USE
|
|
||||||
//! [iplimage]
|
|
||||||
Ptr<IplImage> iplimg(cvLoadImage(imagename.c_str())); // Ptr<T> is safe ref-counting pointer class
|
|
||||||
if(!iplimg)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Can not load image %s\n", imagename.c_str());
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
Mat img = cv::cvarrToMat(iplimg); // cv::Mat replaces the CvMat and IplImage, but it's easy to convert
|
|
||||||
// between the old and the new data structures (by default, only the header
|
|
||||||
// is converted, while the data is shared)
|
|
||||||
//! [iplimage]
|
|
||||||
#else
|
|
||||||
Mat img = imread(imagename); // the newer cvLoadImage alternative, MATLAB-style function
|
|
||||||
if(img.empty())
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Can not load image %s\n", imagename.c_str());
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if( img.empty() ) // check if the image has been loaded properly
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
Mat img_yuv;
|
|
||||||
cvtColor(img, img_yuv, COLOR_BGR2YCrCb); // convert image to YUV color space. The output image will be created automatically
|
|
||||||
|
|
||||||
vector<Mat> planes; // Vector is template vector class, similar to STL's vector. It can store matrices too.
|
|
||||||
split(img_yuv, planes); // split the image into separate color planes
|
|
||||||
|
|
||||||
#if 1
|
|
||||||
// method 1. process Y plane using an iterator
|
|
||||||
MatIterator_<uchar> it = planes[0].begin<uchar>(), it_end = planes[0].end<uchar>();
|
|
||||||
for(; it != it_end; ++it)
|
|
||||||
{
|
|
||||||
double v = *it*1.7 + rand()%21-10;
|
|
||||||
*it = saturate_cast<uchar>(v*v/255.);
|
|
||||||
}
|
|
||||||
|
|
||||||
// method 2. process the first chroma plane using pre-stored row pointer.
|
|
||||||
// method 3. process the second chroma plane using individual element access
|
|
||||||
for( int y = 0; y < img_yuv.rows; y++ )
|
|
||||||
{
|
|
||||||
uchar* Uptr = planes[1].ptr<uchar>(y);
|
|
||||||
for( int x = 0; x < img_yuv.cols; x++ )
|
|
||||||
{
|
|
||||||
Uptr[x] = saturate_cast<uchar>((Uptr[x]-128)/2 + 128);
|
|
||||||
uchar& Vxy = planes[2].at<uchar>(y, x);
|
|
||||||
Vxy = saturate_cast<uchar>((Vxy-128)/2 + 128);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
Mat noise(img.size(), CV_8U); // another Mat constructor; allocates a matrix of the specified size and type
|
|
||||||
randn(noise, Scalar::all(128), Scalar::all(20)); // fills the matrix with normally distributed random values;
|
|
||||||
// there is also randu() for uniformly distributed random number generation
|
|
||||||
GaussianBlur(noise, noise, Size(3, 3), 0.5, 0.5); // blur the noise a bit, kernel size is 3x3 and both sigma's are set to 0.5
|
|
||||||
|
|
||||||
const double brightness_gain = 0;
|
|
||||||
const double contrast_gain = 1.7;
|
|
||||||
#if DEMO_MIXED_API_USE
|
|
||||||
// it's easy to pass the new matrices to the functions that only work with IplImage or CvMat:
|
|
||||||
// step 1) - convert the headers, data will not be copied
|
|
||||||
IplImage cv_planes_0 = planes[0], cv_noise = noise;
|
|
||||||
// step 2) call the function; do not forget unary "&" to form pointers
|
|
||||||
cvAddWeighted(&cv_planes_0, contrast_gain, &cv_noise, 1, -128 + brightness_gain, &cv_planes_0);
|
|
||||||
#else
|
|
||||||
addWeighted(planes[0], contrast_gain, noise, 1, -128 + brightness_gain, planes[0]);
|
|
||||||
#endif
|
|
||||||
const double color_scale = 0.5;
|
|
||||||
// Mat::convertTo() replaces cvConvertScale. One must explicitly specify the output matrix type (we keep it intact - planes[1].type())
|
|
||||||
planes[1].convertTo(planes[1], planes[1].type(), color_scale, 128*(1-color_scale));
|
|
||||||
// alternative form of cv::convertScale if we know the datatype at compile time ("uchar" here).
|
|
||||||
// This expression will not create any temporary arrays and should be almost as fast as the above variant
|
|
||||||
planes[2] = Mat_<uchar>(planes[2]*color_scale + 128*(1-color_scale));
|
|
||||||
|
|
||||||
// Mat::mul replaces cvMul(). Again, no temporary arrays are created in case of simple expressions.
|
|
||||||
planes[0] = planes[0].mul(planes[0], 1./255);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// now merge the results back
|
|
||||||
merge(planes, img_yuv);
|
|
||||||
// and produce the output RGB image
|
|
||||||
cvtColor(img_yuv, img, COLOR_YCrCb2BGR);
|
|
||||||
|
|
||||||
// this is counterpart for cvNamedWindow
|
|
||||||
namedWindow("image with grain", WINDOW_AUTOSIZE);
|
|
||||||
#if DEMO_MIXED_API_USE
|
|
||||||
// this is to demonstrate that img and iplimg really share the data - the result of the above
|
|
||||||
// processing is stored in img and thus in iplimg too.
|
|
||||||
cvShowImage("image with grain", iplimg);
|
|
||||||
#else
|
|
||||||
imshow("image with grain", img);
|
|
||||||
#endif
|
|
||||||
waitKey();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
// all the memory will automatically be released by Vector<>, Mat and Ptr<> destructors.
|
|
||||||
}
|
|
@ -1,149 +0,0 @@
|
|||||||
//! [head]
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include <opencv2/imgproc.hpp>
|
|
||||||
#include "opencv2/imgcodecs.hpp"
|
|
||||||
#include <opencv2/highgui.hpp>
|
|
||||||
|
|
||||||
using namespace cv; // The new C++ interface API is inside this namespace. Import it.
|
|
||||||
using namespace std;
|
|
||||||
//! [head]
|
|
||||||
|
|
||||||
static void help( char* progName)
|
|
||||||
{
|
|
||||||
cout << endl << progName
|
|
||||||
<< " shows how to use cv::Mat and IplImages together (converting back and forth)." << endl
|
|
||||||
<< "Also contains example for image read, splitting the planes, merging back and " << endl
|
|
||||||
<< " color conversion, plus iterating through pixels. " << endl
|
|
||||||
<< "Usage:" << endl
|
|
||||||
<< progName << " [image-name Default: ../data/lena.jpg]" << endl << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! [start]
|
|
||||||
// comment out the define to use only the latest C++ API
|
|
||||||
#define DEMO_MIXED_API_USE
|
|
||||||
|
|
||||||
#ifdef DEMO_MIXED_API_USE
|
|
||||||
# include <opencv2/highgui/highgui_c.h>
|
|
||||||
# include <opencv2/imgcodecs/imgcodecs_c.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int main( int argc, char** argv )
|
|
||||||
{
|
|
||||||
help(argv[0]);
|
|
||||||
const char* imagename = argc > 1 ? argv[1] : "../data/lena.jpg";
|
|
||||||
|
|
||||||
#ifdef DEMO_MIXED_API_USE
|
|
||||||
Ptr<IplImage> IplI(cvLoadImage(imagename)); // Ptr<T> is a safe ref-counting pointer class
|
|
||||||
if(!IplI)
|
|
||||||
{
|
|
||||||
cerr << "Can not load image " << imagename << endl;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
Mat I = cv::cvarrToMat(IplI); // Convert to the new style container. Only header created. Image not copied.
|
|
||||||
#else
|
|
||||||
Mat I = imread(imagename); // the newer cvLoadImage alternative, MATLAB-style function
|
|
||||||
if( I.empty() ) // same as if( !I.data )
|
|
||||||
{
|
|
||||||
cerr << "Can not load image " << imagename << endl;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
//! [start]
|
|
||||||
|
|
||||||
//! [new]
|
|
||||||
// convert image to YUV color space. The output image will be created automatically.
|
|
||||||
Mat I_YUV;
|
|
||||||
cvtColor(I, I_YUV, COLOR_BGR2YCrCb);
|
|
||||||
|
|
||||||
vector<Mat> planes; // Use the STL's vector structure to store multiple Mat objects
|
|
||||||
split(I_YUV, planes); // split the image into separate color planes (Y U V)
|
|
||||||
//! [new]
|
|
||||||
|
|
||||||
#if 1 // change it to 0 if you want to see a blurred and noisy version of this processing
|
|
||||||
//! [scanning]
|
|
||||||
// Mat scanning
|
|
||||||
// Method 1. process Y plane using an iterator
|
|
||||||
MatIterator_<uchar> it = planes[0].begin<uchar>(), it_end = planes[0].end<uchar>();
|
|
||||||
for(; it != it_end; ++it)
|
|
||||||
{
|
|
||||||
double v = *it * 1.7 + rand()%21 - 10;
|
|
||||||
*it = saturate_cast<uchar>(v*v/255);
|
|
||||||
}
|
|
||||||
|
|
||||||
for( int y = 0; y < I_YUV.rows; y++ )
|
|
||||||
{
|
|
||||||
// Method 2. process the first chroma plane using pre-stored row pointer.
|
|
||||||
uchar* Uptr = planes[1].ptr<uchar>(y);
|
|
||||||
for( int x = 0; x < I_YUV.cols; x++ )
|
|
||||||
{
|
|
||||||
Uptr[x] = saturate_cast<uchar>((Uptr[x]-128)/2 + 128);
|
|
||||||
|
|
||||||
// Method 3. process the second chroma plane using individual element access
|
|
||||||
uchar& Vxy = planes[2].at<uchar>(y, x);
|
|
||||||
Vxy = saturate_cast<uchar>((Vxy-128)/2 + 128);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//! [scanning]
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
//! [noisy]
|
|
||||||
Mat noisyI(I.size(), CV_8U); // Create a matrix of the specified size and type
|
|
||||||
|
|
||||||
// Fills the matrix with normally distributed random values (around number with deviation off).
|
|
||||||
// There is also randu() for uniformly distributed random number generation
|
|
||||||
randn(noisyI, Scalar::all(128), Scalar::all(20));
|
|
||||||
|
|
||||||
// blur the noisyI a bit, kernel size is 3x3 and both sigma's are set to 0.5
|
|
||||||
GaussianBlur(noisyI, noisyI, Size(3, 3), 0.5, 0.5);
|
|
||||||
|
|
||||||
const double brightness_gain = 0;
|
|
||||||
const double contrast_gain = 1.7;
|
|
||||||
|
|
||||||
#ifdef DEMO_MIXED_API_USE
|
|
||||||
// To pass the new matrices to the functions that only work with IplImage or CvMat do:
|
|
||||||
// step 1) Convert the headers (tip: data will not be copied).
|
|
||||||
// step 2) call the function (tip: to pass a pointer do not forget unary "&" to form pointers)
|
|
||||||
|
|
||||||
IplImage cv_planes_0 = planes[0], cv_noise = noisyI;
|
|
||||||
cvAddWeighted(&cv_planes_0, contrast_gain, &cv_noise, 1, -128 + brightness_gain, &cv_planes_0);
|
|
||||||
#else
|
|
||||||
addWeighted(planes[0], contrast_gain, noisyI, 1, -128 + brightness_gain, planes[0]);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const double color_scale = 0.5;
|
|
||||||
// Mat::convertTo() replaces cvConvertScale.
|
|
||||||
// One must explicitly specify the output matrix type (we keep it intact - planes[1].type())
|
|
||||||
planes[1].convertTo(planes[1], planes[1].type(), color_scale, 128*(1-color_scale));
|
|
||||||
|
|
||||||
// alternative form of cv::convertScale if we know the datatype at compile time ("uchar" here).
|
|
||||||
// This expression will not create any temporary arrays ( so should be almost as fast as above)
|
|
||||||
planes[2] = Mat_<uchar>(planes[2]*color_scale + 128*(1-color_scale));
|
|
||||||
|
|
||||||
// Mat::mul replaces cvMul(). Again, no temporary arrays are created in case of simple expressions.
|
|
||||||
planes[0] = planes[0].mul(planes[0], 1./255);
|
|
||||||
//! [noisy]
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
//! [end]
|
|
||||||
merge(planes, I_YUV); // now merge the results back
|
|
||||||
cvtColor(I_YUV, I, COLOR_YCrCb2BGR); // and produce the output RGB image
|
|
||||||
|
|
||||||
namedWindow("image with grain", WINDOW_AUTOSIZE); // use this to create images
|
|
||||||
|
|
||||||
#ifdef DEMO_MIXED_API_USE
|
|
||||||
// this is to demonstrate that I and IplI really share the data - the result of the above
|
|
||||||
// processing is stored in I and thus in IplI too.
|
|
||||||
cvShowImage("image with grain", IplI);
|
|
||||||
#else
|
|
||||||
imshow("image with grain", I); // the new MATLAB style function show
|
|
||||||
#endif
|
|
||||||
//! [end]
|
|
||||||
waitKey();
|
|
||||||
|
|
||||||
// Tip: No memory freeing is required!
|
|
||||||
// All the memory will be automatically released by the Vector<>, Mat and Ptr<> destructor.
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,7 +1,6 @@
|
|||||||
/* Snippet code for Operations with images tutorial (not intended to be run but should built successfully) */
|
/* Snippet code for Operations with images tutorial (not intended to be run but should built successfully) */
|
||||||
|
|
||||||
#include "opencv2/core.hpp"
|
#include "opencv2/core.hpp"
|
||||||
#include "opencv2/core/core_c.h"
|
|
||||||
#include "opencv2/imgcodecs.hpp"
|
#include "opencv2/imgcodecs.hpp"
|
||||||
#include "opencv2/imgproc.hpp"
|
#include "opencv2/imgproc.hpp"
|
||||||
#include "opencv2/highgui.hpp"
|
#include "opencv2/highgui.hpp"
|
||||||
@ -128,15 +127,6 @@ int main(int,char**)
|
|||||||
CV_UNUSED(smallImg);
|
CV_UNUSED(smallImg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
|
||||||
//! [C-API conversion]
|
|
||||||
Mat img = imread("image.jpg");
|
|
||||||
IplImage img1 = img;
|
|
||||||
CvMat m = img;
|
|
||||||
//! [C-API conversion]
|
|
||||||
CV_UNUSED(img1);
|
|
||||||
CV_UNUSED(m);
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
//! [BGR to Gray]
|
//! [BGR to Gray]
|
||||||
Mat img = imread("image.jpg"); // loading a 8UC3 image
|
Mat img = imread("image.jpg"); // loading a 8UC3 image
|
||||||
|
Loading…
Reference in New Issue
Block a user