Commit 4c1c3147 authored by catree's avatar catree

Add Java and Python code for the following imgproc tutorials: Affine…

Add Java and Python code for the following imgproc tutorials: Affine Transformations, Histogram Equalization, Histogram Calculation, Histogram Comparison, Back Projection.
parent 3654fb10
...@@ -43,90 +43,118 @@ Code ...@@ -43,90 +43,118 @@ Code
- Compare the histogram of the *base image* with respect to the 2 test histograms, the - Compare the histogram of the *base image* with respect to the 2 test histograms, the
histogram of the lower half base image and with the same base image histogram. histogram of the lower half base image and with the same base image histogram.
- Display the numerical matching parameters obtained. - Display the numerical matching parameters obtained.
@add_toggle_cpp
- **Downloadable code**: Click - **Downloadable code**: Click
[here](https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/Histograms_Matching/compareHist_Demo.cpp) [here](https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/Histograms_Matching/compareHist_Demo.cpp)
- **Code at glance:**
@include samples/cpp/tutorial_code/Histograms_Matching/compareHist_Demo.cpp
@end_toggle
@add_toggle_java
- **Downloadable code**: Click
[here](https://github.com/opencv/opencv/tree/master/samples/java/tutorial_code/Histograms_Matching/histogram_comparison/CompareHistDemo.java)
- **Code at glance:** - **Code at glance:**
@include samples/java/tutorial_code/Histograms_Matching/histogram_comparison/CompareHistDemo.java
@end_toggle
@add_toggle_python
- **Downloadable code**: Click
[here](https://github.com/opencv/opencv/tree/master/samples/python/tutorial_code/Histograms_Matching/histogram_comparison/compareHist_Demo.py)
@include cpp/tutorial_code/Histograms_Matching/compareHist_Demo.cpp - **Code at glance:**
@include samples/python/tutorial_code/Histograms_Matching/histogram_comparison/compareHist_Demo.py
@end_toggle
Explanation Explanation
----------- -----------
-# Declare variables such as the matrices to store the base image and the two other images to - Load the base image (src_base) and the other two test images:
compare ( BGR and HSV )
@code{.cpp} @add_toggle_cpp
Mat src_base, hsv_base; @snippet samples/cpp/tutorial_code/Histograms_Matching/compareHist_Demo.cpp Load three images with different environment settings
Mat src_test1, hsv_test1; @end_toggle
Mat src_test2, hsv_test2;
Mat hsv_half_down; @add_toggle_java
@endcode @snippet samples/java/tutorial_code/Histograms_Matching/histogram_comparison/CompareHistDemo.java Load three images with different environment settings
-# Load the base image (src_base) and the other two test images: @end_toggle
@code{.cpp}
if( argc < 4 ) @add_toggle_python
{ printf("** Error. Usage: ./compareHist_Demo <image_settings0> <image_setting1> <image_settings2>\n"); @snippet samples/python/tutorial_code/Histograms_Matching/histogram_comparison/compareHist_Demo.py Load three images with different environment settings
return -1; @end_toggle
}
- Convert them to HSV format:
src_base = imread( argv[1], 1 );
src_test1 = imread( argv[2], 1 ); @add_toggle_cpp
src_test2 = imread( argv[3], 1 ); @snippet samples/cpp/tutorial_code/Histograms_Matching/compareHist_Demo.cpp Convert to HSV
@endcode @end_toggle
-# Convert them to HSV format:
@code{.cpp} @add_toggle_java
cvtColor( src_base, hsv_base, COLOR_BGR2HSV ); @snippet samples/java/tutorial_code/Histograms_Matching/histogram_comparison/CompareHistDemo.java Convert to HSV
cvtColor( src_test1, hsv_test1, COLOR_BGR2HSV ); @end_toggle
cvtColor( src_test2, hsv_test2, COLOR_BGR2HSV );
@endcode @add_toggle_python
-# Also, create an image of half the base image (in HSV format): @snippet samples/python/tutorial_code/Histograms_Matching/histogram_comparison/compareHist_Demo.py Convert to HSV
@code{.cpp} @end_toggle
hsv_half_down = hsv_base( Range( hsv_base.rows/2, hsv_base.rows - 1 ), Range( 0, hsv_base.cols - 1 ) );
@endcode - Also, create an image of half the base image (in HSV format):
-# Initialize the arguments to calculate the histograms (bins, ranges and channels H and S ).
@code{.cpp} @add_toggle_cpp
int h_bins = 50; int s_bins = 60; @snippet samples/cpp/tutorial_code/Histograms_Matching/compareHist_Demo.cpp Convert to HSV half
int histSize[] = { h_bins, s_bins }; @end_toggle
float h_ranges[] = { 0, 180 }; @add_toggle_java
float s_ranges[] = { 0, 256 }; @snippet samples/java/tutorial_code/Histograms_Matching/histogram_comparison/CompareHistDemo.java Convert to HSV half
@end_toggle
const float* ranges[] = { h_ranges, s_ranges };
@add_toggle_python
int channels[] = { 0, 1 }; @snippet samples/python/tutorial_code/Histograms_Matching/histogram_comparison/compareHist_Demo.py Convert to HSV half
@endcode @end_toggle
-# Create the MatND objects to store the histograms:
@code{.cpp} - Initialize the arguments to calculate the histograms (bins, ranges and channels H and S ).
MatND hist_base;
MatND hist_half_down; @add_toggle_cpp
MatND hist_test1; @snippet samples/cpp/tutorial_code/Histograms_Matching/compareHist_Demo.cpp Using 50 bins for hue and 60 for saturation
MatND hist_test2; @end_toggle
@endcode
-# Calculate the Histograms for the base image, the 2 test images and the half-down base image: @add_toggle_java
@code{.cpp} @snippet samples/java/tutorial_code/Histograms_Matching/histogram_comparison/CompareHistDemo.java Using 50 bins for hue and 60 for saturation
calcHist( &hsv_base, 1, channels, Mat(), hist_base, 2, histSize, ranges, true, false ); @end_toggle
normalize( hist_base, hist_base, 0, 1, NORM_MINMAX, -1, Mat() );
@add_toggle_python
calcHist( &hsv_half_down, 1, channels, Mat(), hist_half_down, 2, histSize, ranges, true, false ); @snippet samples/python/tutorial_code/Histograms_Matching/histogram_comparison/compareHist_Demo.py Using 50 bins for hue and 60 for saturation
normalize( hist_half_down, hist_half_down, 0, 1, NORM_MINMAX, -1, Mat() ); @end_toggle
calcHist( &hsv_test1, 1, channels, Mat(), hist_test1, 2, histSize, ranges, true, false ); - Calculate the Histograms for the base image, the 2 test images and the half-down base image:
normalize( hist_test1, hist_test1, 0, 1, NORM_MINMAX, -1, Mat() );
@add_toggle_cpp
calcHist( &hsv_test2, 1, channels, Mat(), hist_test2, 2, histSize, ranges, true, false ); @snippet samples/cpp/tutorial_code/Histograms_Matching/compareHist_Demo.cpp Calculate the histograms for the HSV images
normalize( hist_test2, hist_test2, 0, 1, NORM_MINMAX, -1, Mat() ); @end_toggle
@endcode
-# Apply sequentially the 4 comparison methods between the histogram of the base image (hist_base) @add_toggle_java
@snippet samples/java/tutorial_code/Histograms_Matching/histogram_comparison/CompareHistDemo.java Calculate the histograms for the HSV images
@end_toggle
@add_toggle_python
@snippet samples/python/tutorial_code/Histograms_Matching/histogram_comparison/compareHist_Demo.py Calculate the histograms for the HSV images
@end_toggle
- Apply sequentially the 4 comparison methods between the histogram of the base image (hist_base)
and the other histograms: and the other histograms:
@code{.cpp}
for( int i = 0; i < 4; i++ ) @add_toggle_cpp
{ int compare_method = i; @snippet samples/cpp/tutorial_code/Histograms_Matching/compareHist_Demo.cpp Apply the histogram comparison methods
double base_base = compareHist( hist_base, hist_base, compare_method ); @end_toggle
double base_half = compareHist( hist_base, hist_half_down, compare_method );
double base_test1 = compareHist( hist_base, hist_test1, compare_method ); @add_toggle_java
double base_test2 = compareHist( hist_base, hist_test2, compare_method ); @snippet samples/java/tutorial_code/Histograms_Matching/histogram_comparison/CompareHistDemo.java Apply the histogram comparison methods
@end_toggle
printf( " Method [%d] Perfect, Base-Half, Base-Test(1), Base-Test(2) : %f, %f, %f, %f \n", i, base_base, base_half , base_test1, base_test2 );
} @add_toggle_python
@endcode @snippet samples/python/tutorial_code/Histograms_Matching/histogram_comparison/compareHist_Demo.py Apply the histogram comparison methods
@end_toggle
Results Results
------- -------
...@@ -144,13 +172,13 @@ Results ...@@ -144,13 +172,13 @@ Results
are from the same source. For the other two test images, we can observe that they have very are from the same source. For the other two test images, we can observe that they have very
different lighting conditions, so the matching should not be very good: different lighting conditions, so the matching should not be very good:
-# Here the numeric results: -# Here the numeric results we got with OpenCV 3.4.1:
*Method* | Base - Base | Base - Half | Base - Test 1 | Base - Test 2 *Method* | Base - Base | Base - Half | Base - Test 1 | Base - Test 2
----------------- | ------------ | ------------ | -------------- | --------------- ----------------- | ------------ | ------------ | -------------- | ---------------
*Correlation* | 1.000000 | 0.930766 | 0.182073 | 0.120447 *Correlation* | 1.000000 | 0.880438 | 0.20457 | 0.0664547
*Chi-square* | 0.000000 | 4.940466 | 21.184536 | 49.273437 *Chi-square* | 0.000000 | 4.6834 | 2697.98 | 4763.8
*Intersection* | 24.391548 | 14.959809 | 3.889029 | 5.775088 *Intersection* | 18.8947 | 13.022 | 5.44085 | 2.58173
*Bhattacharyya* | 0.000000 | 0.222609 | 0.646576 | 0.801869 *Bhattacharyya* | 0.000000 | 0.237887 | 0.679826 | 0.874173
For the *Correlation* and *Intersection* methods, the higher the metric, the more accurate the For the *Correlation* and *Intersection* methods, the higher the metric, the more accurate the
match. As we can see, the match *base-base* is the highest of all as expected. Also we can observe match. As we can see, the match *base-base* is the highest of all as expected. Also we can observe
that the match *base-half* is the second best match (as we predicted). For the other two metrics, that the match *base-half* is the second best match (as we predicted). For the other two metrics,
......
...@@ -22,7 +22,7 @@ Theory ...@@ -22,7 +22,7 @@ Theory
### What is Histogram Equalization? ### What is Histogram Equalization?
- It is a method that improves the contrast in an image, in order to stretch out the intensity - It is a method that improves the contrast in an image, in order to stretch out the intensity
range. range (see also the corresponding <a href="https://en.wikipedia.org/wiki/Histogram_equalization">Wikipedia entry</a>).
- To make it clearer, from the image above, you can see that the pixels seem clustered around the - To make it clearer, from the image above, you can see that the pixels seem clustered around the
middle of the available range of intensities. What Histogram Equalization does is to *stretch middle of the available range of intensities. What Histogram Equalization does is to *stretch
out* this range. Take a look at the figure below: The green circles indicate the out* this range. Take a look at the figure below: The green circles indicate the
...@@ -61,53 +61,105 @@ Code ...@@ -61,53 +61,105 @@ Code
- Convert the original image to grayscale - Convert the original image to grayscale
- Equalize the Histogram by using the OpenCV function @ref cv::equalizeHist - Equalize the Histogram by using the OpenCV function @ref cv::equalizeHist
- Display the source and equalized images in a window. - Display the source and equalized images in a window.
@add_toggle_cpp
- **Downloadable code**: Click - **Downloadable code**: Click
[here](https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/Histograms_Matching/EqualizeHist_Demo.cpp) [here](https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/Histograms_Matching/EqualizeHist_Demo.cpp)
- **Code at glance:** - **Code at glance:**
@include samples/cpp/tutorial_code/Histograms_Matching/EqualizeHist_Demo.cpp @include samples/cpp/tutorial_code/Histograms_Matching/EqualizeHist_Demo.cpp
@end_toggle
@add_toggle_java
- **Downloadable code**: Click
[here](https://github.com/opencv/opencv/tree/master/samples/java/tutorial_code/Histograms_Matching/histogram_equalization/EqualizeHistDemo.java)
- **Code at glance:**
@include samples/java/tutorial_code/Histograms_Matching/histogram_equalization/EqualizeHistDemo.java
@end_toggle
@add_toggle_python
- **Downloadable code**: Click
[here](https://github.com/opencv/opencv/tree/master/samples/python/tutorial_code/Histograms_Matching/histogram_equalization/EqualizeHist_Demo.py)
- **Code at glance:**
@include samples/python/tutorial_code/Histograms_Matching/histogram_equalization/EqualizeHist_Demo.py
@end_toggle
Explanation Explanation
----------- -----------
-# Declare the source and destination images as well as the windows names: - Load the source image:
@code{.cpp}
Mat src, dst; @add_toggle_cpp
@snippet samples/cpp/tutorial_code/Histograms_Matching/EqualizeHist_Demo.cpp Load image
char* source_window = "Source image"; @end_toggle
char* equalized_window = "Equalized Image";
@endcode @add_toggle_java
-# Load the source image: @snippet samples/java/tutorial_code/Histograms_Matching/histogram_equalization/EqualizeHistDemo.java Load image
@code{.cpp} @end_toggle
src = imread( argv[1], 1 );
@add_toggle_python
if( !src.data ) @snippet samples/python/tutorial_code/Histograms_Matching/histogram_equalization/EqualizeHist_Demo.py Load image
{ cout<<"Usage: ./Histogram_Demo <path_to_image>"<<endl; @end_toggle
return -1;}
@endcode - Convert it to grayscale:
-# Convert it to grayscale:
@code{.cpp} @add_toggle_cpp
cvtColor( src, src, COLOR_BGR2GRAY ); @snippet samples/cpp/tutorial_code/Histograms_Matching/EqualizeHist_Demo.cpp Convert to grayscale
@endcode @end_toggle
-# Apply histogram equalization with the function @ref cv::equalizeHist :
@code{.cpp} @add_toggle_java
equalizeHist( src, dst ); @snippet samples/java/tutorial_code/Histograms_Matching/histogram_equalization/EqualizeHistDemo.java Convert to grayscale
@endcode @end_toggle
@add_toggle_python
@snippet samples/python/tutorial_code/Histograms_Matching/histogram_equalization/EqualizeHist_Demo.py Convert to grayscale
@end_toggle
- Apply histogram equalization with the function @ref cv::equalizeHist :
@add_toggle_cpp
@snippet samples/cpp/tutorial_code/Histograms_Matching/EqualizeHist_Demo.cpp Apply Histogram Equalization
@end_toggle
@add_toggle_java
@snippet samples/java/tutorial_code/Histograms_Matching/histogram_equalization/EqualizeHistDemo.java Apply Histogram Equalization
@end_toggle
@add_toggle_python
@snippet samples/python/tutorial_code/Histograms_Matching/histogram_equalization/EqualizeHist_Demo.py Apply Histogram Equalization
@end_toggle
As it can be easily seen, the only arguments are the original image and the output (equalized) As it can be easily seen, the only arguments are the original image and the output (equalized)
image. image.
-# Display both images (original and equalized) : - Display both images (original and equalized):
@code{.cpp}
namedWindow( source_window, WINDOW_AUTOSIZE ); @add_toggle_cpp
namedWindow( equalized_window, WINDOW_AUTOSIZE ); @snippet samples/cpp/tutorial_code/Histograms_Matching/EqualizeHist_Demo.cpp Display results
@end_toggle
imshow( source_window, src );
imshow( equalized_window, dst ); @add_toggle_java
@endcode @snippet samples/java/tutorial_code/Histograms_Matching/histogram_equalization/EqualizeHistDemo.java Display results
-# Wait until user exists the program @end_toggle
@code{.cpp}
waitKey(0); @add_toggle_python
return 0; @snippet samples/python/tutorial_code/Histograms_Matching/histogram_equalization/EqualizeHist_Demo.py Display results
@endcode @end_toggle
- Wait until user exists the program
@add_toggle_cpp
@snippet samples/cpp/tutorial_code/Histograms_Matching/EqualizeHist_Demo.cpp Wait until user exits the program
@end_toggle
@add_toggle_java
@snippet samples/java/tutorial_code/Histograms_Matching/histogram_equalization/EqualizeHistDemo.java Wait until user exits the program
@end_toggle
@add_toggle_python
@snippet samples/python/tutorial_code/Histograms_Matching/histogram_equalization/EqualizeHist_Demo.py Wait until user exits the program
@end_toggle
Results Results
------- -------
......
...@@ -165,6 +165,8 @@ In this section you will learn about the image processing (manipulation) functio ...@@ -165,6 +165,8 @@ In this section you will learn about the image processing (manipulation) functio
- @subpage tutorial_warp_affine - @subpage tutorial_warp_affine
*Languages:* C++, Java, Python
*Compatibility:* \> OpenCV 2.0 *Compatibility:* \> OpenCV 2.0
*Author:* Ana Huamán *Author:* Ana Huamán
...@@ -173,6 +175,8 @@ In this section you will learn about the image processing (manipulation) functio ...@@ -173,6 +175,8 @@ In this section you will learn about the image processing (manipulation) functio
- @subpage tutorial_histogram_equalization - @subpage tutorial_histogram_equalization
*Languages:* C++, Java, Python
*Compatibility:* \> OpenCV 2.0 *Compatibility:* \> OpenCV 2.0
*Author:* Ana Huamán *Author:* Ana Huamán
...@@ -181,6 +185,8 @@ In this section you will learn about the image processing (manipulation) functio ...@@ -181,6 +185,8 @@ In this section you will learn about the image processing (manipulation) functio
- @subpage tutorial_histogram_calculation - @subpage tutorial_histogram_calculation
*Languages:* C++, Java, Python
*Compatibility:* \> OpenCV 2.0 *Compatibility:* \> OpenCV 2.0
*Author:* Ana Huamán *Author:* Ana Huamán
...@@ -189,6 +195,8 @@ In this section you will learn about the image processing (manipulation) functio ...@@ -189,6 +195,8 @@ In this section you will learn about the image processing (manipulation) functio
- @subpage tutorial_histogram_comparison - @subpage tutorial_histogram_comparison
*Languages:* C++, Java, Python
*Compatibility:* \> OpenCV 2.0 *Compatibility:* \> OpenCV 2.0
*Author:* Ana Huamán *Author:* Ana Huamán
...@@ -197,6 +205,8 @@ In this section you will learn about the image processing (manipulation) functio ...@@ -197,6 +205,8 @@ In this section you will learn about the image processing (manipulation) functio
- @subpage tutorial_back_projection - @subpage tutorial_back_projection
*Languages:* C++, Java, Python
*Compatibility:* \> OpenCV 2.0 *Compatibility:* \> OpenCV 2.0
*Author:* Ana Huamán *Author:* Ana Huamán
......
...@@ -17,37 +17,35 @@ using namespace std; ...@@ -17,37 +17,35 @@ using namespace std;
*/ */
int main( int argc, char** argv ) int main( int argc, char** argv )
{ {
Mat src, dst; //! [Load image]
CommandLineParser parser( argc, argv, "{@input | ../data/lena.jpg | input image}" );
const char* source_window = "Source image"; Mat src = imread( parser.get<String>( "@input" ), IMREAD_COLOR );
const char* equalized_window = "Equalized Image"; if( src.empty() )
{
/// Load image cout << "Could not open or find the image!\n" << endl;
CommandLineParser parser( argc, argv, "{@input | ../data/lena.jpg | input image}" ); cout << "Usage: " << argv[0] << " <Input image>" << endl;
src = imread( parser.get<String>( "@input" ), IMREAD_COLOR ); return -1;
if( src.empty() ) }
{ //! [Load image]
cout << "Could not open or find the image!\n" << endl;
cout << "Usage: " << argv[0] << " <Input image>" << endl; //! [Convert to grayscale]
return -1; cvtColor( src, src, COLOR_BGR2GRAY );
} //! [Convert to grayscale]
/// Convert to grayscale //! [Apply Histogram Equalization]
cvtColor( src, src, COLOR_BGR2GRAY ); Mat dst;
equalizeHist( src, dst );
/// Apply Histogram Equalization //! [Apply Histogram Equalization]
equalizeHist( src, dst );
//! [Display results]
/// Display results imshow( "Source image", src );
namedWindow( source_window, WINDOW_AUTOSIZE ); imshow( "Equalized Image", dst );
namedWindow( equalized_window, WINDOW_AUTOSIZE ); //! [Display results]
imshow( source_window, src ); //! [Wait until user exits the program]
imshow( equalized_window, dst ); waitKey();
//! [Wait until user exits the program]
/// Wait until user exits the program
waitKey(0); return 0;
return 0;
} }
...@@ -14,79 +14,93 @@ using namespace cv; ...@@ -14,79 +14,93 @@ using namespace cv;
using namespace std; using namespace std;
/// Global Variables /// Global Variables
Mat src; Mat hsv; Mat hue; Mat hue;
int bins = 25; int bins = 25;
/// Function Headers /// Function Headers
void Hist_and_Backproj(int, void* ); void Hist_and_Backproj(int, void* );
/** /**
* @function main * @function main
*/ */
int main( int, char** argv ) int main( int argc, char* argv[] )
{ {
/// Read the image //! [Read the image]
src = imread( argv[1], IMREAD_COLOR ); CommandLineParser parser( argc, argv, "{@input | | input image}" );
Mat src = imread( parser.get<String>( "@input" ) );
if( src.empty() ) if( src.empty() )
{ cout<<"Usage: ./calcBackProject_Demo1 <path_to_image>"<<endl; {
return -1; cout << "Could not open or find the image!\n" << endl;
cout << "Usage: " << argv[0] << " <Input image>" << endl;
return -1;
} }
//! [Read the image]
/// Transform it to HSV
cvtColor( src, hsv, COLOR_BGR2HSV ); //! [Transform it to HSV]
Mat hsv;
/// Use only the Hue value cvtColor( src, hsv, COLOR_BGR2HSV );
hue.create( hsv.size(), hsv.depth() ); //! [Transform it to HSV]
int ch[] = { 0, 0 };
mixChannels( &hsv, 1, &hue, 1, ch, 1 ); //! [Use only the Hue value]
hue.create(hsv.size(), hsv.depth());
/// Create Trackbar to enter the number of bins int ch[] = { 0, 0 };
const char* window_image = "Source image"; mixChannels( &hsv, 1, &hue, 1, ch, 1 );
namedWindow( window_image, WINDOW_AUTOSIZE ); //! [Use only the Hue value]
createTrackbar("* Hue bins: ", window_image, &bins, 180, Hist_and_Backproj );
Hist_and_Backproj(0, 0); //! [Create Trackbar to enter the number of bins]
const char* window_image = "Source image";
/// Show the image namedWindow( window_image );
imshow( window_image, src ); createTrackbar("* Hue bins: ", window_image, &bins, 180, Hist_and_Backproj );
Hist_and_Backproj(0, 0);
/// Wait until user exits the program //! [Create Trackbar to enter the number of bins]
waitKey(0);
return 0; //! [Show the image]
imshow( window_image, src );
// Wait until user exits the program
waitKey();
//! [Show the image]
return 0;
} }
/** /**
* @function Hist_and_Backproj * @function Hist_and_Backproj
* @brief Callback to Trackbar * @brief Callback to Trackbar
*/ */
void Hist_and_Backproj(int, void* ) void Hist_and_Backproj(int, void* )
{ {
MatND hist; //! [initialize]
int histSize = MAX( bins, 2 ); int histSize = MAX( bins, 2 );
float hue_range[] = { 0, 180 }; float hue_range[] = { 0, 180 };
const float* ranges = { hue_range }; const float* ranges = { hue_range };
//! [initialize]
/// Get the Histogram and normalize it
calcHist( &hue, 1, 0, Mat(), hist, 1, &histSize, &ranges, true, false ); //! [Get the Histogram and normalize it]
normalize( hist, hist, 0, 255, NORM_MINMAX, -1, Mat() ); Mat hist;
calcHist( &hue, 1, 0, Mat(), hist, 1, &histSize, &ranges, true, false );
/// Get Backprojection normalize( hist, hist, 0, 255, NORM_MINMAX, -1, Mat() );
MatND backproj; //! [Get the Histogram and normalize it]
calcBackProject( &hue, 1, 0, hist, backproj, &ranges, 1, true );
//! [Get Backprojection]
/// Draw the backproj Mat backproj;
imshow( "BackProj", backproj ); calcBackProject( &hue, 1, 0, hist, backproj, &ranges, 1, true );
//! [Get Backprojection]
/// Draw the histogram
int w = 400; int h = 400; //! [Draw the backproj]
int bin_w = cvRound( (double) w / histSize ); imshow( "BackProj", backproj );
Mat histImg = Mat::zeros( w, h, CV_8UC3 ); //! [Draw the backproj]
for( int i = 0; i < bins; i ++ ) //! [Draw the histogram]
{ rectangle( histImg, Point( i*bin_w, h ), Point( (i+1)*bin_w, h - cvRound( hist.at<float>(i)*h/255.0 ) ), Scalar( 0, 0, 255 ), -1 ); } int w = 400, h = 400;
int bin_w = cvRound( (double) w / histSize );
imshow( "Histogram", histImg ); Mat histImg = Mat::zeros( h, w, CV_8UC3 );
for (int i = 0; i < bins; i++)
{
rectangle( histImg, Point( i*bin_w, h ), Point( (i+1)*bin_w, h - cvRound( hist.at<float>(i)*h/255.0 ) ),
Scalar( 0, 0, 255 ), FILLED );
}
imshow( "Histogram", histImg );
//! [Draw the histogram]
} }
...@@ -14,10 +14,9 @@ using namespace cv; ...@@ -14,10 +14,9 @@ using namespace cv;
using namespace std; using namespace std;
/// Global Variables /// Global Variables
Mat src; Mat hsv; Mat src, hsv, mask;
Mat mask;
int lo = 20; int up = 20; int low = 20, up = 20;
const char* window_image = "Source image"; const char* window_image = "Source image";
/// Function Headers /// Function Headers
...@@ -29,23 +28,24 @@ void pickPoint (int event, int x, int y, int, void* ); ...@@ -29,23 +28,24 @@ void pickPoint (int event, int x, int y, int, void* );
*/ */
int main( int, char** argv ) int main( int, char** argv )
{ {
/// Read the image /// Read the image
src = imread( argv[1], IMREAD_COLOR ); src = imread( argv[1] );
/// Transform it to HSV
cvtColor( src, hsv, COLOR_BGR2HSV ); /// Transform it to HSV
cvtColor( src, hsv, COLOR_BGR2HSV );
/// Show the image
namedWindow( window_image, WINDOW_AUTOSIZE ); /// Show the image
imshow( window_image, src ); namedWindow( window_image );
imshow( window_image, src );
/// Set Trackbars for floodfill thresholds
createTrackbar( "Low thresh", window_image, &lo, 255, 0 ); /// Set Trackbars for floodfill thresholds
createTrackbar( "High thresh", window_image, &up, 255, 0 ); createTrackbar( "Low thresh", window_image, &low, 255, 0 );
/// Set a Mouse Callback createTrackbar( "High thresh", window_image, &up, 255, 0 );
setMouseCallback( window_image, pickPoint, 0 ); /// Set a Mouse Callback
setMouseCallback( window_image, pickPoint, 0 );
waitKey(0);
return 0; waitKey();
return 0;
} }
/** /**
...@@ -53,25 +53,27 @@ int main( int, char** argv ) ...@@ -53,25 +53,27 @@ int main( int, char** argv )
*/ */
void pickPoint (int event, int x, int y, int, void* ) void pickPoint (int event, int x, int y, int, void* )
{ {
if( event != EVENT_LBUTTONDOWN ) if( event != EVENT_LBUTTONDOWN )
{ return; } {
return;
}
// Fill and get the mask // Fill and get the mask
Point seed = Point( x, y ); Point seed = Point( x, y );
int newMaskVal = 255; int newMaskVal = 255;
Scalar newVal = Scalar( 120, 120, 120 ); Scalar newVal = Scalar( 120, 120, 120 );
int connectivity = 8; int connectivity = 8;
int flags = connectivity + (newMaskVal << 8 ) + FLOODFILL_FIXED_RANGE + FLOODFILL_MASK_ONLY; int flags = connectivity + (newMaskVal << 8 ) + FLOODFILL_FIXED_RANGE + FLOODFILL_MASK_ONLY;
Mat mask2 = Mat::zeros( src.rows + 2, src.cols + 2, CV_8UC1 ); Mat mask2 = Mat::zeros( src.rows + 2, src.cols + 2, CV_8U );
floodFill( src, mask2, seed, newVal, 0, Scalar( lo, lo, lo ), Scalar( up, up, up), flags ); floodFill( src, mask2, seed, newVal, 0, Scalar( low, low, low ), Scalar( up, up, up), flags );
mask = mask2( Range( 1, mask2.rows - 1 ), Range( 1, mask2.cols - 1 ) ); mask = mask2( Range( 1, mask2.rows - 1 ), Range( 1, mask2.cols - 1 ) );
imshow( "Mask", mask ); imshow( "Mask", mask );
Hist_and_Backproj( ); Hist_and_Backproj( );
} }
/** /**
...@@ -79,26 +81,25 @@ void pickPoint (int event, int x, int y, int, void* ) ...@@ -79,26 +81,25 @@ void pickPoint (int event, int x, int y, int, void* )
*/ */
void Hist_and_Backproj( ) void Hist_and_Backproj( )
{ {
MatND hist; Mat hist;
int h_bins = 30; int s_bins = 32; int h_bins = 30; int s_bins = 32;
int histSize[] = { h_bins, s_bins }; int histSize[] = { h_bins, s_bins };
float h_range[] = { 0, 179 };
float s_range[] = { 0, 255 };
const float* ranges[] = { h_range, s_range };
int channels[] = { 0, 1 }; float h_range[] = { 0, 180 };
float s_range[] = { 0, 256 };
const float* ranges[] = { h_range, s_range };
/// Get the Histogram and normalize it int channels[] = { 0, 1 };
calcHist( &hsv, 1, channels, mask, hist, 2, histSize, ranges, true, false );
normalize( hist, hist, 0, 255, NORM_MINMAX, -1, Mat() ); /// Get the Histogram and normalize it
calcHist( &hsv, 1, channels, mask, hist, 2, histSize, ranges, true, false );
/// Get Backprojection normalize( hist, hist, 0, 255, NORM_MINMAX, -1, Mat() );
MatND backproj;
calcBackProject( &hsv, 1, channels, hist, backproj, ranges, 1, true );
/// Draw the backproj /// Get Backprojection
imshow( "BackProj", backproj ); Mat backproj;
calcBackProject( &hsv, 1, channels, hist, backproj, ranges, 1, true );
/// Draw the backproj
imshow( "BackProj", backproj );
} }
...@@ -17,72 +17,73 @@ using namespace cv; ...@@ -17,72 +17,73 @@ using namespace cv;
*/ */
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
Mat src, dst; //! [Load image]
CommandLineParser parser( argc, argv, "{@input | ../data/lena.jpg | input image}" );
/// Load image Mat src = imread( parser.get<String>( "@input" ), IMREAD_COLOR );
String imageName( "../data/lena.jpg" ); // by default if( src.empty() )
{
if (argc > 1) return -1;
{ }
imageName = argv[1]; //! [Load image]
}
//! [Separate the image in 3 places ( B, G and R )]
src = imread( imageName, IMREAD_COLOR ); vector<Mat> bgr_planes;
split( src, bgr_planes );
if( src.empty() ) //! [Separate the image in 3 places ( B, G and R )]
{ return -1; }
//! [Establish the number of bins]
/// Separate the image in 3 places ( B, G and R ) int histSize = 256;
vector<Mat> bgr_planes; //! [Establish the number of bins]
split( src, bgr_planes );
//! [Set the ranges ( for B,G,R) )]
/// Establish the number of bins float range[] = { 0, 256 }; //the upper boundary is exclusive
int histSize = 256; const float* histRange = { range };
//! [Set the ranges ( for B,G,R) )]
/// Set the ranges ( for B,G,R) )
float range[] = { 0, 256 } ; //! [Set histogram param]
const float* histRange = { range }; bool uniform = true, accumulate = false;
//! [Set histogram param]
bool uniform = true; bool accumulate = false;
//! [Compute the histograms]
Mat b_hist, g_hist, r_hist; Mat b_hist, g_hist, r_hist;
calcHist( &bgr_planes[0], 1, 0, Mat(), b_hist, 1, &histSize, &histRange, uniform, accumulate );
/// Compute the histograms: calcHist( &bgr_planes[1], 1, 0, Mat(), g_hist, 1, &histSize, &histRange, uniform, accumulate );
calcHist( &bgr_planes[0], 1, 0, Mat(), b_hist, 1, &histSize, &histRange, uniform, accumulate ); calcHist( &bgr_planes[2], 1, 0, Mat(), r_hist, 1, &histSize, &histRange, uniform, accumulate );
calcHist( &bgr_planes[1], 1, 0, Mat(), g_hist, 1, &histSize, &histRange, uniform, accumulate ); //! [Compute the histograms]
calcHist( &bgr_planes[2], 1, 0, Mat(), r_hist, 1, &histSize, &histRange, uniform, accumulate );
//! [Draw the histograms for B, G and R]
// Draw the histograms for B, G and R int hist_w = 512, hist_h = 400;
int hist_w = 512; int hist_h = 400; int bin_w = cvRound( (double) hist_w/histSize );
int bin_w = cvRound( (double) hist_w/histSize );
Mat histImage( hist_h, hist_w, CV_8UC3, Scalar( 0,0,0) );
Mat histImage( hist_h, hist_w, CV_8UC3, Scalar( 0,0,0) ); //! [Draw the histograms for B, G and R]
/// Normalize the result to [ 0, histImage.rows ] //! [Normalize the result to ( 0, histImage.rows )]
normalize(b_hist, b_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() ); normalize(b_hist, b_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() );
normalize(g_hist, g_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() ); normalize(g_hist, g_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() );
normalize(r_hist, r_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() ); normalize(r_hist, r_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() );
//! [Normalize the result to ( 0, histImage.rows )]
/// Draw for each channel
for( int i = 1; i < histSize; i++ ) //! [Draw for each channel]
{ for( int i = 1; i < histSize; i++ )
line( histImage, Point( bin_w*(i-1), hist_h - cvRound(b_hist.at<float>(i-1)) ) , {
Point( bin_w*(i), hist_h - cvRound(b_hist.at<float>(i)) ), line( histImage, Point( bin_w*(i-1), hist_h - cvRound(b_hist.at<float>(i-1)) ),
Scalar( 255, 0, 0), 2, 8, 0 ); Point( bin_w*(i), hist_h - cvRound(b_hist.at<float>(i)) ),
line( histImage, Point( bin_w*(i-1), hist_h - cvRound(g_hist.at<float>(i-1)) ) , Scalar( 255, 0, 0), 2, 8, 0 );
Point( bin_w*(i), hist_h - cvRound(g_hist.at<float>(i)) ), line( histImage, Point( bin_w*(i-1), hist_h - cvRound(g_hist.at<float>(i-1)) ),
Scalar( 0, 255, 0), 2, 8, 0 ); Point( bin_w*(i), hist_h - cvRound(g_hist.at<float>(i)) ),
line( histImage, Point( bin_w*(i-1), hist_h - cvRound(r_hist.at<float>(i-1)) ) , Scalar( 0, 255, 0), 2, 8, 0 );
Point( bin_w*(i), hist_h - cvRound(r_hist.at<float>(i)) ), line( histImage, Point( bin_w*(i-1), hist_h - cvRound(r_hist.at<float>(i-1)) ),
Scalar( 0, 0, 255), 2, 8, 0 ); Point( bin_w*(i), hist_h - cvRound(r_hist.at<float>(i)) ),
} Scalar( 0, 0, 255), 2, 8, 0 );
}
/// Display //! [Draw for each channel]
namedWindow("calcHist Demo", WINDOW_AUTOSIZE );
imshow("calcHist Demo", histImage ); //! [Display]
imshow("Source image", src );
waitKey(0); imshow("calcHist Demo", histImage );
waitKey();
return 0; //! [Display]
return 0;
} }
...@@ -12,42 +12,43 @@ ...@@ -12,42 +12,43 @@
using namespace std; using namespace std;
using namespace cv; using namespace cv;
const char* keys =
"{ help h| | Print help message. }"
"{ input1 | | Path to input image 1. }"
"{ input2 | | Path to input image 2. }"
"{ input3 | | Path to input image 3. }";
/** /**
* @function main * @function main
*/ */
int main( int argc, char** argv ) int main( int argc, char** argv )
{ {
Mat src_base, hsv_base; //! [Load three images with different environment settings]
Mat src_test1, hsv_test1; CommandLineParser parser( argc, argv, keys );
Mat src_test2, hsv_test2; Mat src_base = imread( parser.get<String>("input1") );
Mat hsv_half_down; Mat src_test1 = imread( parser.get<String>("input2") );
Mat src_test2 = imread( parser.get<String>("input3") );
/// Load three images with different environment settings if( src_base.empty() || src_test1.empty() || src_test2.empty() )
if( argc < 4 )
{ {
printf("** Error. Usage: ./compareHist_Demo <image_settings0> <image_settings1> <image_settings2>\n"); cout << "Could not open or find the images!\n" << endl;
parser.printMessage();
return -1; return -1;
} }
//! [Load three images with different environment settings]
src_base = imread( argv[1], IMREAD_COLOR ); //! [Convert to HSV]
src_test1 = imread( argv[2], IMREAD_COLOR ); Mat hsv_base, hsv_test1, hsv_test2;
src_test2 = imread( argv[3], IMREAD_COLOR );
if(src_base.empty() || src_test1.empty() || src_test2.empty())
{
cout << "Can't read one of the images" << endl;
return -1;
}
/// Convert to HSV
cvtColor( src_base, hsv_base, COLOR_BGR2HSV ); cvtColor( src_base, hsv_base, COLOR_BGR2HSV );
cvtColor( src_test1, hsv_test1, COLOR_BGR2HSV ); cvtColor( src_test1, hsv_test1, COLOR_BGR2HSV );
cvtColor( src_test2, hsv_test2, COLOR_BGR2HSV ); cvtColor( src_test2, hsv_test2, COLOR_BGR2HSV );
//! [Convert to HSV]
hsv_half_down = hsv_base( Range( hsv_base.rows/2, hsv_base.rows - 1 ), Range( 0, hsv_base.cols - 1 ) ); //! [Convert to HSV half]
Mat hsv_half_down = hsv_base( Range( hsv_base.rows/2, hsv_base.rows ), Range( 0, hsv_base.cols ) );
//! [Convert to HSV half]
/// Using 50 bins for hue and 60 for saturation //! [Using 50 bins for hue and 60 for saturation]
int h_bins = 50; int s_bins = 60; int h_bins = 50, s_bins = 60;
int histSize[] = { h_bins, s_bins }; int histSize[] = { h_bins, s_bins };
// hue varies from 0 to 179, saturation from 0 to 255 // hue varies from 0 to 179, saturation from 0 to 255
...@@ -56,17 +57,13 @@ int main( int argc, char** argv ) ...@@ -56,17 +57,13 @@ int main( int argc, char** argv )
const float* ranges[] = { h_ranges, s_ranges }; const float* ranges[] = { h_ranges, s_ranges };
// Use the o-th and 1-st channels // Use the 0-th and 1-st channels
int channels[] = { 0, 1 }; int channels[] = { 0, 1 };
//! [Using 50 bins for hue and 60 for saturation]
//! [Calculate the histograms for the HSV images]
Mat hist_base, hist_half_down, hist_test1, hist_test2;
/// Histograms
MatND hist_base;
MatND hist_half_down;
MatND hist_test1;
MatND hist_test2;
/// Calculate the histograms for the HSV images
calcHist( &hsv_base, 1, channels, Mat(), hist_base, 2, histSize, ranges, true, false ); calcHist( &hsv_base, 1, channels, Mat(), hist_base, 2, histSize, ranges, true, false );
normalize( hist_base, hist_base, 0, 1, NORM_MINMAX, -1, Mat() ); normalize( hist_base, hist_base, 0, 1, NORM_MINMAX, -1, Mat() );
...@@ -78,20 +75,21 @@ int main( int argc, char** argv ) ...@@ -78,20 +75,21 @@ int main( int argc, char** argv )
calcHist( &hsv_test2, 1, channels, Mat(), hist_test2, 2, histSize, ranges, true, false ); calcHist( &hsv_test2, 1, channels, Mat(), hist_test2, 2, histSize, ranges, true, false );
normalize( hist_test2, hist_test2, 0, 1, NORM_MINMAX, -1, Mat() ); normalize( hist_test2, hist_test2, 0, 1, NORM_MINMAX, -1, Mat() );
//! [Calculate the histograms for the HSV images]
/// Apply the histogram comparison methods //! [Apply the histogram comparison methods]
for( int i = 0; i < 4; i++ ) for( int compare_method = 0; compare_method < 4; compare_method++ )
{ {
int compare_method = i;
double base_base = compareHist( hist_base, hist_base, compare_method ); double base_base = compareHist( hist_base, hist_base, compare_method );
double base_half = compareHist( hist_base, hist_half_down, compare_method ); double base_half = compareHist( hist_base, hist_half_down, compare_method );
double base_test1 = compareHist( hist_base, hist_test1, compare_method ); double base_test1 = compareHist( hist_base, hist_test1, compare_method );
double base_test2 = compareHist( hist_base, hist_test2, compare_method ); double base_test2 = compareHist( hist_base, hist_test2, compare_method );
printf( " Method [%d] Perfect, Base-Half, Base-Test(1), Base-Test(2) : %f, %f, %f, %f \n", i, base_base, base_half , base_test1, base_test2 ); cout << "Method " << compare_method << " Perfect, Base-Half, Base-Test(1), Base-Test(2) : "
<< base_base << " / " << base_half << " / " << base_test1 << " / " << base_test2 << endl;
} }
//! [Apply the histogram comparison methods]
printf( "Done \n" ); cout << "Done \n";
return 0; return 0;
} }
...@@ -12,77 +12,71 @@ ...@@ -12,77 +12,71 @@
using namespace cv; using namespace cv;
using namespace std; using namespace std;
/// Global variables
const char* source_window = "Source image";
const char* warp_window = "Warp";
const char* warp_rotate_window = "Warp + Rotate";
/** /**
* @function main * @function main
*/ */
int main( int argc, char** argv ) int main( int argc, char** argv )
{ {
Point2f srcTri[3]; //! [Load the image]
Point2f dstTri[3]; CommandLineParser parser( argc, argv, "{@input | ../data/lena.jpg | input image}" );
Mat src = imread( parser.get<String>( "@input" ) );
Mat rot_mat( 2, 3, CV_32FC1 ); if( src.empty() )
Mat warp_mat( 2, 3, CV_32FC1 ); {
Mat src, warp_dst, warp_rotate_dst; cout << "Could not open or find the image!\n" << endl;
cout << "Usage: " << argv[0] << " <Input image>" << endl;
/// Load the image return -1;
CommandLineParser parser( argc, argv, "{@input | ../data/lena.jpg | input image}" ); }
src = imread( parser.get<String>( "@input" ), IMREAD_COLOR ); //! [Load the image]
if( src.empty() )
{ //! [Set your 3 points to calculate the Affine Transform]
cout << "Could not open or find the image!\n" << endl; Point2f srcTri[3];
cout << "Usage: " << argv[0] << " <Input image>" << endl; srcTri[0] = Point2f( 0.f, 0.f );
return -1; srcTri[1] = Point2f( src.cols - 1.f, 0.f );
} srcTri[2] = Point2f( 0.f, src.rows - 1.f );
/// Set the dst image the same type and size as src Point2f dstTri[3];
warp_dst = Mat::zeros( src.rows, src.cols, src.type() ); dstTri[0] = Point2f( 0.f, src.rows*0.33f );
dstTri[1] = Point2f( src.cols*0.85f, src.rows*0.25f );
/// Set your 3 points to calculate the Affine Transform dstTri[2] = Point2f( src.cols*0.15f, src.rows*0.7f );
srcTri[0] = Point2f( 0,0 ); //! [Set your 3 points to calculate the Affine Transform]
srcTri[1] = Point2f( src.cols - 1.f, 0 );
srcTri[2] = Point2f( 0, src.rows - 1.f ); //! [Get the Affine Transform]
Mat warp_mat = getAffineTransform( srcTri, dstTri );
dstTri[0] = Point2f( src.cols*0.0f, src.rows*0.33f ); //! [Get the Affine Transform]
dstTri[1] = Point2f( src.cols*0.85f, src.rows*0.25f );
dstTri[2] = Point2f( src.cols*0.15f, src.rows*0.7f ); //! [Apply the Affine Transform just found to the src image]
/// Set the dst image the same type and size as src
/// Get the Affine Transform Mat warp_dst = Mat::zeros( src.rows, src.cols, src.type() );
warp_mat = getAffineTransform( srcTri, dstTri );
warpAffine( src, warp_dst, warp_mat, warp_dst.size() );
/// Apply the Affine Transform just found to the src image //! [Apply the Affine Transform just found to the src image]
warpAffine( src, warp_dst, warp_mat, warp_dst.size() );
/** Rotating the image after Warp */
/** Rotating the image after Warp */
//! [Compute a rotation matrix with respect to the center of the image]
/// Compute a rotation matrix with respect to the center of the image Point center = Point( warp_dst.cols/2, warp_dst.rows/2 );
Point center = Point( warp_dst.cols/2, warp_dst.rows/2 ); double angle = -50.0;
double angle = -50.0; double scale = 0.6;
double scale = 0.6; //! [Compute a rotation matrix with respect to the center of the image]
/// Get the rotation matrix with the specifications above //! [Get the rotation matrix with the specifications above]
rot_mat = getRotationMatrix2D( center, angle, scale ); Mat rot_mat = getRotationMatrix2D( center, angle, scale );
//! [Get the rotation matrix with the specifications above]
/// Rotate the warped image
warpAffine( warp_dst, warp_rotate_dst, rot_mat, warp_dst.size() ); //! [Rotate the warped image]
Mat warp_rotate_dst;
warpAffine( warp_dst, warp_rotate_dst, rot_mat, warp_dst.size() );
/// Show what you got //! [Rotate the warped image]
namedWindow( source_window, WINDOW_AUTOSIZE );
imshow( source_window, src ); //! [Show what you got]
imshow( "Source image", src );
namedWindow( warp_window, WINDOW_AUTOSIZE ); imshow( "Warp", warp_dst );
imshow( warp_window, warp_dst ); imshow( "Warp + Rotate", warp_rotate_dst );
//! [Show what you got]
namedWindow( warp_rotate_window, WINDOW_AUTOSIZE );
imshow( warp_rotate_window, warp_rotate_dst ); //! [Wait until user exits the program]
waitKey();
/// Wait until user exits the program //! [Wait until user exits the program]
waitKey(0);
return 0;
return 0;
} }
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Image;
import java.util.Arrays;
import java.util.List;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfFloat;
import org.opencv.core.MatOfInt;
import org.opencv.core.Point;
import org.opencv.core.Scalar;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
class CalcBackProject1 {
private Mat hue;
private Mat histImg = new Mat();
private JFrame frame;
private JLabel imgLabel;
private JLabel backprojLabel;
private JLabel histImgLabel;
private static final int MAX_SLIDER = 180;
private int bins = 25;
public CalcBackProject1(String[] args) {
//! [Read the image]
if (args.length != 1) {
System.err.println("You must supply one argument that corresponds to the path to the image.");
System.exit(0);
}
Mat src = Imgcodecs.imread(args[0]);
if (src.empty()) {
System.err.println("Empty image: " + args[0]);
System.exit(0);
}
//! [Read the image]
//! [Transform it to HSV]
Mat hsv = new Mat();
Imgproc.cvtColor(src, hsv, Imgproc.COLOR_BGR2HSV);
//! [Transform it to HSV]
//! [Use only the Hue value]
hue = new Mat(hsv.size(), hsv.depth());
Core.mixChannels(Arrays.asList(hsv), Arrays.asList(hue), new MatOfInt(0, 0));
//! [Use only the Hue value]
// Create and set up the window.
frame = new JFrame("Back Projection 1 demo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Set up the content pane.
Image img = HighGui.toBufferedImage(src);
addComponentsToPane(frame.getContentPane(), img);
//! [Show the image]
// Use the content pane's default BorderLayout. No need for
// setLayout(new BorderLayout());
// Display the window.
frame.pack();
frame.setVisible(true);
//! [Show the image]
}
private void addComponentsToPane(Container pane, Image img) {
if (!(pane.getLayout() instanceof BorderLayout)) {
pane.add(new JLabel("Container doesn't use BorderLayout!"));
return;
}
//! [Create Trackbar to enter the number of bins]
JPanel sliderPanel = new JPanel();
sliderPanel.setLayout(new BoxLayout(sliderPanel, BoxLayout.PAGE_AXIS));
sliderPanel.add(new JLabel("* Hue bins: "));
JSlider slider = new JSlider(0, MAX_SLIDER, bins);
slider.setMajorTickSpacing(25);
slider.setMinorTickSpacing(5);
slider.setPaintTicks(true);
slider.setPaintLabels(true);
slider.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
JSlider source = (JSlider) e.getSource();
bins = source.getValue();
update();
}
});
sliderPanel.add(slider);
pane.add(sliderPanel, BorderLayout.PAGE_START);
//! [Create Trackbar to enter the number of bins]
JPanel imgPanel = new JPanel();
imgLabel = new JLabel(new ImageIcon(img));
imgPanel.add(imgLabel);
backprojLabel = new JLabel();
imgPanel.add(backprojLabel);
histImgLabel = new JLabel();
imgPanel.add(histImgLabel);
pane.add(imgPanel, BorderLayout.CENTER);
}
private void update() {
//! [initialize]
int histSize = Math.max(bins, 2);
float[] hueRange = {0, 180};
//! [initialize]
//! [Get the Histogram and normalize it]
Mat hist = new Mat();
List<Mat> hueList = Arrays.asList(hue);
Imgproc.calcHist(hueList, new MatOfInt(0), new Mat(), hist, new MatOfInt(histSize), new MatOfFloat(hueRange), false);
Core.normalize(hist, hist, 0, 255, Core.NORM_MINMAX);
//! [Get the Histogram and normalize it]
//! [Get Backprojection]
Mat backproj = new Mat();
Imgproc.calcBackProject(hueList, new MatOfInt(0), hist, backproj, new MatOfFloat(hueRange), 1);
//! [Get Backprojection]
//! [Draw the backproj]
Image backprojImg = HighGui.toBufferedImage(backproj);
backprojLabel.setIcon(new ImageIcon(backprojImg));
//! [Draw the backproj]
//! [Draw the histogram]
int w = 400, h = 400;
int binW = (int) Math.round((double) w / histSize);
histImg = Mat.zeros(h, w, CvType.CV_8UC3);
float[] histData = new float[(int) (hist.total() * hist.channels())];
hist.get(0, 0, histData);
for (int i = 0; i < bins; i++) {
Imgproc.rectangle(histImg, new Point(i * binW, h),
new Point((i + 1) * binW, h - Math.round(histData[i] * h / 255.0)), new Scalar(0, 0, 255), Core.FILLED);
}
Image histImage = HighGui.toBufferedImage(histImg);
histImgLabel.setIcon(new ImageIcon(histImage));
//! [Draw the histogram]
frame.repaint();
frame.pack();
}
}
public class CalcBackProjectDemo1 {
public static void main(String[] args) {
// Load the native OpenCV library
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
// Schedule a job for the event dispatch thread:
// creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new CalcBackProject1(args);
}
});
}
}
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Image;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Arrays;
import java.util.List;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfFloat;
import org.opencv.core.MatOfInt;
import org.opencv.core.Point;
import org.opencv.core.Range;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
class CalcBackProject2 {
private Mat src;
private Mat hsv = new Mat();
private Mat mask = new Mat();
private JFrame frame;
private JLabel imgLabel;
private JLabel backprojLabel;
private JLabel maskImgLabel;
private static final int MAX_SLIDER = 255;
private int low = 20;
private int up = 20;
public CalcBackProject2(String[] args) {
/// Read the image
if (args.length != 1) {
System.err.println("You must supply one argument that corresponds to the path to the image.");
System.exit(0);
}
src = Imgcodecs.imread(args[0]);
if (src.empty()) {
System.err.println("Empty image: " + args[0]);
System.exit(0);
}
/// Transform it to HSV
Imgproc.cvtColor(src, hsv, Imgproc.COLOR_BGR2HSV);
// Create and set up the window.
frame = new JFrame("Back Projection 2 demo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Set up the content pane.
Image img = HighGui.toBufferedImage(src);
addComponentsToPane(frame.getContentPane(), img);
// Use the content pane's default BorderLayout. No need for
// setLayout(new BorderLayout());
// Display the window.
frame.pack();
frame.setVisible(true);
}
private void addComponentsToPane(Container pane, Image img) {
if (!(pane.getLayout() instanceof BorderLayout)) {
pane.add(new JLabel("Container doesn't use BorderLayout!"));
return;
}
/// Set Trackbars for floodfill thresholds
JPanel sliderPanel = new JPanel();
sliderPanel.setLayout(new BoxLayout(sliderPanel, BoxLayout.PAGE_AXIS));
sliderPanel.add(new JLabel("Low thresh"));
JSlider slider = new JSlider(0, MAX_SLIDER, low);
slider.setMajorTickSpacing(20);
slider.setMinorTickSpacing(10);
slider.setPaintTicks(true);
slider.setPaintLabels(true);
slider.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
JSlider source = (JSlider) e.getSource();
low = source.getValue();
}
});
sliderPanel.add(slider);
pane.add(sliderPanel, BorderLayout.PAGE_START);
sliderPanel.add(new JLabel("High thresh"));
slider = new JSlider(0, MAX_SLIDER, up);
slider.setMajorTickSpacing(20);
slider.setMinorTickSpacing(10);
slider.setPaintTicks(true);
slider.setPaintLabels(true);
slider.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
JSlider source = (JSlider) e.getSource();
up = source.getValue();
}
});
sliderPanel.add(slider);
pane.add(sliderPanel, BorderLayout.PAGE_START);
JPanel imgPanel = new JPanel();
imgLabel = new JLabel(new ImageIcon(img));
/// Set a Mouse Callback
imgLabel.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
update(e.getX(), e.getY());
}
});
imgPanel.add(imgLabel);
maskImgLabel = new JLabel();
imgPanel.add(maskImgLabel);
backprojLabel = new JLabel();
imgPanel.add(backprojLabel);
pane.add(imgPanel, BorderLayout.CENTER);
}
private void update(int x, int y) {
// Fill and get the mask
Point seed = new Point(x, y);
int newMaskVal = 255;
Scalar newVal = new Scalar(120, 120, 120);
int connectivity = 8;
int flags = connectivity + (newMaskVal << 8) + Imgproc.FLOODFILL_FIXED_RANGE + Imgproc.FLOODFILL_MASK_ONLY;
Mat mask2 = Mat.zeros(src.rows() + 2, src.cols() + 2, CvType.CV_8U);
Imgproc.floodFill(src, mask2, seed, newVal, new Rect(), new Scalar(low, low, low), new Scalar(up, up, up), flags);
mask = mask2.submat(new Range(1, mask2.rows() - 1), new Range(1, mask2.cols() - 1));
Image maskImg = HighGui.toBufferedImage(mask);
maskImgLabel.setIcon(new ImageIcon(maskImg));
int hBins = 30, sBins = 32;
int[] histSize = { hBins, sBins };
float[] ranges = { 0, 180, 0, 256 };
int[] channels = { 0, 1 };
/// Get the Histogram and normalize it
Mat hist = new Mat();
List<Mat> hsvList = Arrays.asList(hsv);
Imgproc.calcHist(hsvList, new MatOfInt(channels), mask, hist, new MatOfInt(histSize), new MatOfFloat(ranges), false );
Core.normalize(hist, hist, 0, 255, Core.NORM_MINMAX);
/// Get Backprojection
Mat backproj = new Mat();
Imgproc.calcBackProject(hsvList, new MatOfInt(channels), hist, backproj, new MatOfFloat(ranges), 1);
Image backprojImg = HighGui.toBufferedImage(backproj);
backprojLabel.setIcon(new ImageIcon(backprojImg));
frame.repaint();
frame.pack();
}
}
public class CalcBackProjectDemo2 {
public static void main(String[] args) {
// Load the native OpenCV library
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
// Schedule a job for the event dispatch thread:
// creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new CalcBackProject2(args);
}
});
}
}
import java.util.ArrayList;
import java.util.List;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfFloat;
import org.opencv.core.MatOfInt;
import org.opencv.core.Point;
import org.opencv.core.Scalar;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
class CalcHist {
public void run(String[] args) {
//! [Load image]
String filename = args.length > 0 ? args[0] : "../data/lena.jpg";
Mat src = Imgcodecs.imread(filename);
if (src.empty()) {
System.err.println("Cannot read image: " + filename);
System.exit(0);
}
//! [Load image]
//! [Separate the image in 3 places ( B, G and R )]
List<Mat> bgrPlanes = new ArrayList<>();
Core.split(src, bgrPlanes);
//! [Separate the image in 3 places ( B, G and R )]
//! [Establish the number of bins]
int histSize = 256;
//! [Establish the number of bins]
//! [Set the ranges ( for B,G,R) )]
float[] range = {0, 256}; //the upper boundary is exclusive
MatOfFloat histRange = new MatOfFloat(range);
//! [Set the ranges ( for B,G,R) )]
//! [Set histogram param]
boolean accumulate = false;
//! [Set histogram param]
//! [Compute the histograms]
Mat bHist = new Mat(), gHist = new Mat(), rHist = new Mat();
Imgproc.calcHist(bgrPlanes, new MatOfInt(0), new Mat(), bHist, new MatOfInt(histSize), histRange, accumulate);
Imgproc.calcHist(bgrPlanes, new MatOfInt(1), new Mat(), gHist, new MatOfInt(histSize), histRange, accumulate);
Imgproc.calcHist(bgrPlanes, new MatOfInt(2), new Mat(), rHist, new MatOfInt(histSize), histRange, accumulate);
//! [Compute the histograms]
//! [Draw the histograms for B, G and R]
int histW = 512, histH = 400;
int binW = (int) Math.round((double) histW / histSize);
Mat histImage = new Mat( histH, histW, CvType.CV_8UC3, new Scalar( 0,0,0) );
//! [Draw the histograms for B, G and R]
//! [Normalize the result to ( 0, histImage.rows )]
Core.normalize(bHist, bHist, 0, histImage.rows(), Core.NORM_MINMAX);
Core.normalize(gHist, gHist, 0, histImage.rows(), Core.NORM_MINMAX);
Core.normalize(rHist, rHist, 0, histImage.rows(), Core.NORM_MINMAX);
//! [Normalize the result to ( 0, histImage.rows )]
//! [Draw for each channel]
float[] bHistData = new float[(int) (bHist.total() * bHist.channels())];
bHist.get(0, 0, bHistData);
float[] gHistData = new float[(int) (gHist.total() * gHist.channels())];
gHist.get(0, 0, gHistData);
float[] rHistData = new float[(int) (rHist.total() * rHist.channels())];
rHist.get(0, 0, rHistData);
for( int i = 1; i < histSize; i++ ) {
Imgproc.line(histImage, new Point(binW * (i - 1), histH - Math.round(bHistData[i - 1])),
new Point(binW * (i), histH - Math.round(bHistData[i])), new Scalar(255, 0, 0), 2);
Imgproc.line(histImage, new Point(binW * (i - 1), histH - Math.round(gHistData[i - 1])),
new Point(binW * (i), histH - Math.round(gHistData[i])), new Scalar(0, 255, 0), 2);
Imgproc.line(histImage, new Point(binW * (i - 1), histH - Math.round(rHistData[i - 1])),
new Point(binW * (i), histH - Math.round(rHistData[i])), new Scalar(0, 0, 255), 2);
}
//! [Draw for each channel]
//! [Display]
HighGui.imshow( "Source image", src );
HighGui.imshow( "calcHist Demo", histImage );
HighGui.waitKey(0);
//! [Display]
System.exit(0);
}
}
public class CalcHistDemo {
public static void main(String[] args) {
// Load the native OpenCV library
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
new CalcHist().run(args);
}
}
import java.util.Arrays;
import java.util.List;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfFloat;
import org.opencv.core.MatOfInt;
import org.opencv.core.Range;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
class CompareHist {
public void run(String[] args) {
//! [Load three images with different environment settings]
if (args.length != 3) {
System.err.println("You must supply 3 arguments that correspond to the paths to 3 images.");
System.exit(0);
}
Mat srcBase = Imgcodecs.imread(args[0]);
Mat srcTest1 = Imgcodecs.imread(args[1]);
Mat srcTest2 = Imgcodecs.imread(args[2]);
if (srcBase.empty() || srcTest1.empty() || srcTest2.empty()) {
System.err.println("Cannot read the images");
System.exit(0);
}
//! [Load three images with different environment settings]
//! [Convert to HSV]
Mat hsvBase = new Mat(), hsvTest1 = new Mat(), hsvTest2 = new Mat();
Imgproc.cvtColor( srcBase, hsvBase, Imgproc.COLOR_BGR2HSV );
Imgproc.cvtColor( srcTest1, hsvTest1, Imgproc.COLOR_BGR2HSV );
Imgproc.cvtColor( srcTest2, hsvTest2, Imgproc.COLOR_BGR2HSV );
//! [Convert to HSV]
//! [Convert to HSV half]
Mat hsvHalfDown = hsvBase.submat( new Range( hsvBase.rows()/2, hsvBase.rows() - 1 ), new Range( 0, hsvBase.cols() - 1 ) );
//! [Convert to HSV half]
//! [Using 50 bins for hue and 60 for saturation]
int hBins = 50, sBins = 60;
int[] histSize = { hBins, sBins };
// hue varies from 0 to 179, saturation from 0 to 255
float[] ranges = { 0, 180, 0, 256 };
// Use the 0-th and 1-st channels
int[] channels = { 0, 1 };
//! [Using 50 bins for hue and 60 for saturation]
//! [Calculate the histograms for the HSV images]
Mat histBase = new Mat(), histHalfDown = new Mat(), histTest1 = new Mat(), histTest2 = new Mat();
List<Mat> hsvBaseList = Arrays.asList(hsvBase);
Imgproc.calcHist(hsvBaseList, new MatOfInt(channels), new Mat(), histBase, new MatOfInt(histSize), new MatOfFloat(ranges), false);
Core.normalize(histBase, histBase, 0, 1, Core.NORM_MINMAX);
List<Mat> hsvHalfDownList = Arrays.asList(hsvHalfDown);
Imgproc.calcHist(hsvHalfDownList, new MatOfInt(channels), new Mat(), histHalfDown, new MatOfInt(histSize), new MatOfFloat(ranges), false);
Core.normalize(histHalfDown, histHalfDown, 0, 1, Core.NORM_MINMAX);
List<Mat> hsvTest1List = Arrays.asList(hsvTest1);
Imgproc.calcHist(hsvTest1List, new MatOfInt(channels), new Mat(), histTest1, new MatOfInt(histSize), new MatOfFloat(ranges), false);
Core.normalize(histTest1, histTest1, 0, 1, Core.NORM_MINMAX);
List<Mat> hsvTest2List = Arrays.asList(hsvTest2);
Imgproc.calcHist(hsvTest2List, new MatOfInt(channels), new Mat(), histTest2, new MatOfInt(histSize), new MatOfFloat(ranges), false);
Core.normalize(histTest2, histTest2, 0, 1, Core.NORM_MINMAX);
//! [Calculate the histograms for the HSV images]
//! [Apply the histogram comparison methods]
for( int compareMethod = 0; compareMethod < 4; compareMethod++ ) {
double baseBase = Imgproc.compareHist( histBase, histBase, compareMethod );
double baseHalf = Imgproc.compareHist( histBase, histHalfDown, compareMethod );
double baseTest1 = Imgproc.compareHist( histBase, histTest1, compareMethod );
double baseTest2 = Imgproc.compareHist( histBase, histTest2, compareMethod );
System.out.println("Method " + compareMethod + " Perfect, Base-Half, Base-Test(1), Base-Test(2) : " + baseBase + " / " + baseHalf
+ " / " + baseTest1 + " / " + baseTest2);
}
//! [Apply the histogram comparison methods]
}
}
public class CompareHistDemo {
public static void main(String[] args) {
// Load the native OpenCV library
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
new CompareHist().run(args);
}
}
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
class EqualizeHist {
public void run(String[] args) {
//! [Load image]
String filename = args.length > 0 ? args[0] : "../data/lena.jpg";
Mat src = Imgcodecs.imread(filename);
if (src.empty()) {
System.err.println("Cannot read image: " + filename);
System.exit(0);
}
//! [Load image]
//! [Convert to grayscale]
Imgproc.cvtColor(src, src, Imgproc.COLOR_BGR2GRAY);
//! [Convert to grayscale]
//! [Apply Histogram Equalization]
Mat dst = new Mat();
Imgproc.equalizeHist( src, dst );
//! [Apply Histogram Equalization]
//! [Display results]
HighGui.imshow( "Source image", src );
HighGui.imshow( "Equalized Image", dst );
//! [Display results]
//! [Wait until user exits the program]
HighGui.waitKey(0);
//! [Wait until user exits the program]
System.exit(0);
}
}
public class EqualizeHistDemo {
public static void main(String[] args) {
// Load the native OpenCV library
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
new EqualizeHist().run(args);
}
}
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfPoint2f;
import org.opencv.core.Point;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
class GeometricTransforms {
public void run(String[] args) {
//! [Load the image]
String filename = args.length > 0 ? args[0] : "../data/lena.jpg";
Mat src = Imgcodecs.imread(filename);
if (src.empty()) {
System.err.println("Cannot read image: " + filename);
System.exit(0);
}
//! [Load the image]
//! [Set your 3 points to calculate the Affine Transform]
Point[] srcTri = new Point[3];
srcTri[0] = new Point( 0, 0 );
srcTri[1] = new Point( src.cols() - 1, 0 );
srcTri[2] = new Point( 0, src.rows() - 1 );
Point[] dstTri = new Point[3];
dstTri[0] = new Point( 0, src.rows()*0.33 );
dstTri[1] = new Point( src.cols()*0.85, src.rows()*0.25 );
dstTri[2] = new Point( src.cols()*0.15, src.rows()*0.7 );
//! [Set your 3 points to calculate the Affine Transform]
//! [Get the Affine Transform]
Mat warpMat = Imgproc.getAffineTransform( new MatOfPoint2f(srcTri), new MatOfPoint2f(dstTri) );
//! [Get the Affine Transform]
//! [Apply the Affine Transform just found to the src image]
Mat warpDst = Mat.zeros( src.rows(), src.cols(), src.type() );
Imgproc.warpAffine( src, warpDst, warpMat, warpDst.size() );
//! [Apply the Affine Transform just found to the src image]
/** Rotating the image after Warp */
//! [Compute a rotation matrix with respect to the center of the image]
Point center = new Point(warpDst.cols() / 2, warpDst.rows() / 2);
double angle = -50.0;
double scale = 0.6;
//! [Compute a rotation matrix with respect to the center of the image]
//! [Get the rotation matrix with the specifications above]
Mat rotMat = Imgproc.getRotationMatrix2D( center, angle, scale );
//! [Get the rotation matrix with the specifications above]
//! [Rotate the warped image]
Mat warpRotateDst = new Mat();
Imgproc.warpAffine( warpDst, warpRotateDst, rotMat, warpDst.size() );
//! [Rotate the warped image]
//! [Show what you got]
HighGui.imshow( "Source image", src );
HighGui.imshow( "Warp", warpDst );
HighGui.imshow( "Warp + Rotate", warpRotateDst );
//! [Show what you got]
//! [Wait until user exits the program]
HighGui.waitKey(0);
//! [Wait until user exits the program]
System.exit(0);
}
}
public class GeometricTransformsDemo {
public static void main(String[] args) {
// Load the native OpenCV library
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
new GeometricTransforms().run(args);
}
}
from __future__ import print_function
from __future__ import division
import cv2 as cv
import numpy as np
import argparse
def Hist_and_Backproj(val):
## [initialize]
bins = val
histSize = max(bins, 2)
ranges = [0, 180] # hue_range
## [initialize]
## [Get the Histogram and normalize it]
hist = cv.calcHist([hue], [0], None, [histSize], ranges, accumulate=False)
cv.normalize(hist, hist, alpha=0, beta=255, norm_type=cv.NORM_MINMAX)
## [Get the Histogram and normalize it]
## [Get Backprojection]
backproj = cv.calcBackProject([hue], [0], hist, ranges, scale=1)
## [Get Backprojection]
## [Draw the backproj]
cv.imshow('BackProj', backproj)
## [Draw the backproj]
## [Draw the histogram]
w = 400
h = 400
bin_w = int(round(w / histSize))
histImg = np.zeros((h, w, 3), dtype=np.uint8)
for i in range(bins):
cv.rectangle(histImg, (i*bin_w, h), ( (i+1)*bin_w, h - int(round( hist[i]*h/255.0 )) ), (0, 0, 255), cv.FILLED)
cv.imshow('Histogram', histImg)
## [Draw the histogram]
## [Read the image]
parser = argparse.ArgumentParser(description='Code for Back Projection tutorial.')
parser.add_argument('--input', help='Path to input image.')
args = parser.parse_args()
src = cv.imread(args.input)
if src is None:
print('Could not open or find the image:', args.input)
exit(0)
## [Read the image]
## [Transform it to HSV]
hsv = cv.cvtColor(src, cv.COLOR_BGR2HSV)
## [Transform it to HSV]
## [Use only the Hue value]
ch = (0, 0)
hue = np.empty(hsv.shape, hsv.dtype)
cv.mixChannels([hsv], [hue], ch)
## [Use only the Hue value]
## [Create Trackbar to enter the number of bins]
window_image = 'Source image'
cv.namedWindow(window_image)
bins = 25
cv.createTrackbar('* Hue bins: ', window_image, bins, 180, Hist_and_Backproj )
Hist_and_Backproj(bins)
## [Create Trackbar to enter the number of bins]
## [Show the image]
cv.imshow(window_image, src)
cv.waitKey()
## [Show the image]
from __future__ import print_function
import cv2 as cv
import numpy as np
import argparse
low = 20
up = 20
def callback_low(val):
global low
low = val
def callback_up(val):
global up
up = val
def pickPoint(event, x, y, flags, param):
if event != cv.EVENT_LBUTTONDOWN:
return
# Fill and get the mask
seed = (x, y)
newMaskVal = 255
newVal = (120, 120, 120)
connectivity = 8
flags = connectivity + (newMaskVal << 8 ) + cv.FLOODFILL_FIXED_RANGE + cv.FLOODFILL_MASK_ONLY
mask2 = np.zeros((src.shape[0] + 2, src.shape[1] + 2), dtype=np.uint8)
print('low:', low, 'up:', up)
cv.floodFill(src, mask2, seed, newVal, (low, low, low), (up, up, up), flags)
mask = mask2[1:-1,1:-1]
cv.imshow('Mask', mask)
Hist_and_Backproj(mask)
def Hist_and_Backproj(mask):
h_bins = 30
s_bins = 32
histSize = [h_bins, s_bins]
h_range = [0, 180]
s_range = [0, 256]
ranges = h_range + s_range # Concat list
channels = [0, 1]
# Get the Histogram and normalize it
hist = cv.calcHist([hsv], channels, mask, histSize, ranges, accumulate=False)
cv.normalize(hist, hist, alpha=0, beta=255, norm_type=cv.NORM_MINMAX)
# Get Backprojection
backproj = cv.calcBackProject([hsv], channels, hist, ranges, scale=1)
# Draw the backproj
cv.imshow('BackProj', backproj)
# Read the image
parser = argparse.ArgumentParser(description='Code for Back Projection tutorial.')
parser.add_argument('--input', help='Path to input image.')
args = parser.parse_args()
src = cv.imread(args.input)
if src is None:
print('Could not open or find the image:', args.input)
exit(0)
# Transform it to HSV
hsv = cv.cvtColor(src, cv.COLOR_BGR2HSV)
# Show the image
window_image = 'Source image'
cv.namedWindow(window_image)
cv.imshow(window_image, src)
# Set Trackbars for floodfill thresholds
cv.createTrackbar('Low thresh', window_image, low, 255, callback_low)
cv.createTrackbar('High thresh', window_image, up, 255, callback_up)
# Set a Mouse Callback
cv.setMouseCallback(window_image, pickPoint)
cv.waitKey()
from __future__ import print_function
from __future__ import division
import cv2 as cv
import numpy as np
import argparse
## [Load image]
parser = argparse.ArgumentParser(description='Code for Histogram Calculation tutorial.')
parser.add_argument('--input', help='Path to input image.', default='../data/lena.jpg')
args = parser.parse_args()
src = cv.imread(args.input)
if src is None:
print('Could not open or find the image:', args.input)
exit(0)
## [Load image]
## [Separate the image in 3 places ( B, G and R )]
bgr_planes = cv.split(src)
## [Separate the image in 3 places ( B, G and R )]
## [Establish the number of bins]
histSize = 256
## [Establish the number of bins]
## [Set the ranges ( for B,G,R) )]
histRange = (0, 256) # the upper boundary is exclusive
## [Set the ranges ( for B,G,R) )]
## [Set histogram param]
accumulate = False
## [Set histogram param]
## [Compute the histograms]
b_hist = cv.calcHist(bgr_planes, [0], None, [histSize], histRange, accumulate=accumulate)
g_hist = cv.calcHist(bgr_planes, [1], None, [histSize], histRange, accumulate=accumulate)
r_hist = cv.calcHist(bgr_planes, [2], None, [histSize], histRange, accumulate=accumulate)
## [Compute the histograms]
## [Draw the histograms for B, G and R]
hist_w = 512
hist_h = 400
bin_w = int(round( hist_w/histSize ))
histImage = np.zeros((hist_h, hist_w, 3), dtype=np.uint8)
## [Draw the histograms for B, G and R]
## [Normalize the result to ( 0, histImage.rows )]
cv.normalize(b_hist, b_hist, alpha=0, beta=hist_h, norm_type=cv.NORM_MINMAX)
cv.normalize(g_hist, g_hist, alpha=0, beta=hist_h, norm_type=cv.NORM_MINMAX)
cv.normalize(r_hist, r_hist, alpha=0, beta=hist_h, norm_type=cv.NORM_MINMAX)
## [Normalize the result to ( 0, histImage.rows )]
## [Draw for each channel]
for i in range(1, histSize):
cv.line(histImage, ( bin_w*(i-1), hist_h - int(round(b_hist[i-1])) ),
( bin_w*(i), hist_h - int(round(b_hist[i])) ),
( 255, 0, 0), thickness=2)
cv.line(histImage, ( bin_w*(i-1), hist_h - int(round(g_hist[i-1])) ),
( bin_w*(i), hist_h - int(round(g_hist[i])) ),
( 0, 255, 0), thickness=2)
cv.line(histImage, ( bin_w*(i-1), hist_h - int(round(r_hist[i-1])) ),
( bin_w*(i), hist_h - int(round(r_hist[i])) ),
( 0, 0, 255), thickness=2)
## [Draw for each channel]
## [Display]
cv.imshow('Source image', src)
cv.imshow('calcHist Demo', histImage)
cv.waitKey()
## [Display]
from __future__ import print_function
from __future__ import division
import cv2 as cv
import numpy as np
import argparse
## [Load three images with different environment settings]
parser = argparse.ArgumentParser(description='Code for Histogram Comparison tutorial.')
parser.add_argument('--input1', help='Path to input image 1.')
parser.add_argument('--input2', help='Path to input image 2.')
parser.add_argument('--input3', help='Path to input image 3.')
args = parser.parse_args()
src_base = cv.imread(args.input1)
src_test1 = cv.imread(args.input2)
src_test2 = cv.imread(args.input3)
if src_base is None or src_test1 is None or src_test2 is None:
print('Could not open or find the images!')
exit(0)
## [Load three images with different environment settings]
## [Convert to HSV]
hsv_base = cv.cvtColor(src_base, cv.COLOR_BGR2HSV)
hsv_test1 = cv.cvtColor(src_test1, cv.COLOR_BGR2HSV)
hsv_test2 = cv.cvtColor(src_test2, cv.COLOR_BGR2HSV)
## [Convert to HSV]
## [Convert to HSV half]
hsv_half_down = hsv_base[hsv_base.shape[0]//2:,:]
## [Convert to HSV half]
## [Using 50 bins for hue and 60 for saturation]
h_bins = 50
s_bins = 60
histSize = [h_bins, s_bins]
# hue varies from 0 to 179, saturation from 0 to 255
h_ranges = [0, 180]
s_ranges = [0, 256]
ranges = h_ranges + s_ranges # concat lists
# Use the 0-th and 1-st channels
channels = [0, 1]
## [Using 50 bins for hue and 60 for saturation]
## [Calculate the histograms for the HSV images]
hist_base = cv.calcHist([hsv_base], channels, None, histSize, ranges, accumulate=False)
cv.normalize(hist_base, hist_base, alpha=0, beta=1, norm_type=cv.NORM_MINMAX)
hist_half_down = cv.calcHist([hsv_half_down], channels, None, histSize, ranges, accumulate=False)
cv.normalize(hist_half_down, hist_half_down, alpha=0, beta=1, norm_type=cv.NORM_MINMAX)
hist_test1 = cv.calcHist([hsv_test1], channels, None, histSize, ranges, accumulate=False)
cv.normalize(hist_test1, hist_test1, alpha=0, beta=1, norm_type=cv.NORM_MINMAX)
hist_test2 = cv.calcHist([hsv_test2], channels, None, histSize, ranges, accumulate=False)
cv.normalize(hist_test2, hist_test2, alpha=0, beta=1, norm_type=cv.NORM_MINMAX)
## [Calculate the histograms for the HSV images]
## [Apply the histogram comparison methods]
for compare_method in range(4):
base_base = cv.compareHist(hist_base, hist_base, compare_method)
base_half = cv.compareHist(hist_base, hist_half_down, compare_method)
base_test1 = cv.compareHist(hist_base, hist_test1, compare_method)
base_test2 = cv.compareHist(hist_base, hist_test2, compare_method)
print('Method:', compare_method, 'Perfect, Base-Half, Base-Test(1), Base-Test(2) :',\
base_base, '/', base_half, '/', base_test1, '/', base_test2)
## [Apply the histogram comparison methods]
from __future__ import print_function
import cv2 as cv
import argparse
## [Load image]
parser = argparse.ArgumentParser(description='Code for Histogram Equalization tutorial.')
parser.add_argument('--input', help='Path to input image.', default='../data/lena.jpg')
args = parser.parse_args()
src = cv.imread(args.input)
if src is None:
print('Could not open or find the image:', args.input)
exit(0)
## [Load image]
## [Convert to grayscale]
src = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
## [Convert to grayscale]
## [Apply Histogram Equalization]
dst = cv.equalizeHist(src);
## [Apply Histogram Equalization]
## [Display results]
cv.imshow('Source image', src)
cv.imshow('Equalized Image', dst)
## [Display results]
## [Wait until user exits the program]
cv.waitKey()
## [Wait until user exits the program]
from __future__ import print_function
import cv2 as cv
import numpy as np
import argparse
## [Load the image]
parser = argparse.ArgumentParser(description='Code for Affine Transformations tutorial.')
parser.add_argument('--input', help='Path to input image.', default='../data/lena.jpg')
args = parser.parse_args()
src = cv.imread(args.input)
if src is None:
print('Could not open or find the image:', args.input)
exit(0)
## [Load the image]
## [Set your 3 points to calculate the Affine Transform]
srcTri = np.array( [[0, 0], [src.shape[1] - 1, 0], [0, src.shape[0] - 1]] ).astype(np.float32)
dstTri = np.array( [[0, src.shape[1]*0.33], [src.shape[1]*0.85, src.shape[0]*0.25], [src.shape[1]*0.15, src.shape[0]*0.7]] ).astype(np.float32)
## [Set your 3 points to calculate the Affine Transform]
## [Get the Affine Transform]
warp_mat = cv.getAffineTransform(srcTri, dstTri)
## [Get the Affine Transform]
## [Apply the Affine Transform just found to the src image]
warp_dst = cv.warpAffine(src, warp_mat, (src.shape[1], src.shape[0]))
## [Apply the Affine Transform just found to the src image]
# Rotating the image after Warp
## [Compute a rotation matrix with respect to the center of the image]
center = (warp_dst.shape[1]//2, warp_dst.shape[0]//2)
angle = -50
scale = 0.6
## [Compute a rotation matrix with respect to the center of the image]
## [Get the rotation matrix with the specifications above]
rot_mat = cv.getRotationMatrix2D( center, angle, scale )
## [Get the rotation matrix with the specifications above]
## [Rotate the warped image]
warp_rotate_dst = cv.warpAffine(warp_dst, rot_mat, (warp_dst.shape[1], warp_dst.shape[0]))
## [Rotate the warped image]
## [Show what you got]
cv.imshow('Source image', src)
cv.imshow('Warp', warp_dst)
cv.imshow('Warp + Rotate', warp_rotate_dst)
## [Show what you got]
## [Wait until user exits the program]
cv.waitKey()
## [Wait until user exits the program]
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment