Commit a11ef265 authored by catree's avatar catree

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

Add Java and Python code for the following imgproc tutorials: Finding contours in your image, Convex Hull, Creating Bounding boxes and circles for contours, Creating Bounding rotated boxes and ellipses for contours, Image Moments, Point Polygon Test.
parent 93f2fd39
...@@ -15,55 +15,167 @@ Theory ...@@ -15,55 +15,167 @@ Theory
Code Code
---- ----
@add_toggle_cpp
This tutorial code's is shown lines below. You can also download it from This tutorial code's is shown lines below. You can also download it from
[here](https://github.com/opencv/opencv/tree/3.4/samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp) [here](https://github.com/opencv/opencv/tree/3.4/samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp)
@include samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp @include samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp
@end_toggle
@add_toggle_java
This tutorial code's is shown lines below. You can also download it from
[here](https://github.com/opencv/opencv/tree/3.4/samples/java/tutorial_code/ShapeDescriptors/bounding_rects_circles/GeneralContoursDemo1.java)
@include samples/java/tutorial_code/ShapeDescriptors/bounding_rects_circles/GeneralContoursDemo1.java
@end_toggle
@add_toggle_python
This tutorial code's is shown lines below. You can also download it from
[here](https://github.com/opencv/opencv/tree/3.4/samples/python/tutorial_code/ShapeDescriptors/bounding_rects_circles/generalContours_demo1.py)
@include samples/python/tutorial_code/ShapeDescriptors/bounding_rects_circles/generalContours_demo1.py
@end_toggle
Explanation Explanation
----------- -----------
The main function is rather simple, as follows from the comments we do the following: The main function is rather simple, as follows from the comments we do the following:
-# Open the image, convert it into grayscale and blur it to get rid of the noise. - Open the image, convert it into grayscale and blur it to get rid of the noise.
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp setup
-# Create a window with header "Source" and display the source file in it. @add_toggle_cpp
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp createWindow @snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp setup
-# Create a trackbar on the source_window and assign a callback function to it @end_toggle
@add_toggle_java
@snippet samples/java/tutorial_code/ShapeDescriptors/bounding_rects_circles/GeneralContoursDemo1.java setup
@end_toggle
@add_toggle_python
@snippet samples/python/tutorial_code/ShapeDescriptors/bounding_rects_circles/generalContours_demo1.py setup
@end_toggle
- Create a window with header "Source" and display the source file in it.
@add_toggle_cpp
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp createWindow
@end_toggle
@add_toggle_java
@snippet samples/java/tutorial_code/ShapeDescriptors/bounding_rects_circles/GeneralContoursDemo1.java createWindow
@end_toggle
@add_toggle_python
@snippet samples/python/tutorial_code/ShapeDescriptors/bounding_rects_circles/generalContours_demo1.py createWindow
@end_toggle
- Create a trackbar on the `source_window` and assign a callback function to it.
In general callback functions are used to react to some kind of signal, in our In general callback functions are used to react to some kind of signal, in our
case it's trackbar's state change. case it's trackbar's state change.
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp taskbar Explicit one-time call of `thresh_callback` is necessary to display
-# Explicit one-time call of `thresh_callback` is necessary to display
the "Contours" window simultaniously with the "Source" window. the "Contours" window simultaniously with the "Source" window.
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp callback00
-# Wait for user to close the windows.
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp waitForIt
@add_toggle_cpp
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp trackbar
@end_toggle
The callback function `thresh_callback` does all the interesting job. @add_toggle_java
@snippet samples/java/tutorial_code/ShapeDescriptors/bounding_rects_circles/GeneralContoursDemo1.java trackbar
@end_toggle
@add_toggle_python
@snippet samples/python/tutorial_code/ShapeDescriptors/bounding_rects_circles/generalContours_demo1.py trackbar
@end_toggle
-# Writes to `threshold_output` the threshold of the grayscale picture (you can check out about thresholding @ref tutorial_threshold "here"). The callback function does all the interesting job.
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp threshold
-# Finds contours and saves them to the vectors `contour` and `hierarchy`.
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp findContours
-# For every found contour we now apply approximation to polygons
with accuracy +-3 and stating that the curve must me closed.
After that we find a bounding rect for every polygon and save it to `boundRect`. - Use @ref cv::Canny to detect edges in the images.
@add_toggle_cpp
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp Canny
@end_toggle
@add_toggle_java
@snippet samples/java/tutorial_code/ShapeDescriptors/bounding_rects_circles/GeneralContoursDemo1.java Canny
@end_toggle
@add_toggle_python
@snippet samples/python/tutorial_code/ShapeDescriptors/bounding_rects_circles/generalContours_demo1.py Canny
@end_toggle
- Finds contours and saves them to the vectors `contour` and `hierarchy`.
@add_toggle_cpp
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp findContours
@end_toggle
@add_toggle_java
@snippet samples/java/tutorial_code/ShapeDescriptors/bounding_rects_circles/GeneralContoursDemo1.java findContours
@end_toggle
@add_toggle_python
@snippet samples/python/tutorial_code/ShapeDescriptors/bounding_rects_circles/generalContours_demo1.py findContours
@end_toggle
- For every found contour we now apply approximation to polygons
with accuracy +-3 and stating that the curve must be closed.
After that we find a bounding rect for every polygon and save it to `boundRect`.
At last we find a minimum enclosing circle for every polygon and At last we find a minimum enclosing circle for every polygon and
save it to `center` and `radius` vectors. save it to `center` and `radius` vectors.
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp allthework
@add_toggle_cpp
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp allthework
@end_toggle
@add_toggle_java
@snippet samples/java/tutorial_code/ShapeDescriptors/bounding_rects_circles/GeneralContoursDemo1.java allthework
@end_toggle
@add_toggle_python
@snippet samples/python/tutorial_code/ShapeDescriptors/bounding_rects_circles/generalContours_demo1.py allthework
@end_toggle
We found everything we need, all we have to do is to draw. We found everything we need, all we have to do is to draw.
-# Create new Mat of unsigned 8-bit chars, filled with zeros. - Create new Mat of unsigned 8-bit chars, filled with zeros.
It will contain all the drawings we are going to make (rects and circles). It will contain all the drawings we are going to make (rects and circles).
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp zeroMat
-# For every contour: pick a random color, draw the contour, the bounding rectangle and @add_toggle_cpp
the minimal enclosing circle with it, @snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp zeroMat
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp forContour @end_toggle
-# Display the results: create a new window "Contours" and show everything we added to drawings on it.
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp showDrawings @add_toggle_java
@snippet samples/java/tutorial_code/ShapeDescriptors/bounding_rects_circles/GeneralContoursDemo1.java zeroMat
@end_toggle
@add_toggle_python
@snippet samples/python/tutorial_code/ShapeDescriptors/bounding_rects_circles/generalContours_demo1.py zeroMat
@end_toggle
- For every contour: pick a random color, draw the contour, the bounding rectangle and
the minimal enclosing circle with it.
@add_toggle_cpp
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp forContour
@end_toggle
@add_toggle_java
@snippet samples/java/tutorial_code/ShapeDescriptors/bounding_rects_circles/GeneralContoursDemo1.java forContour
@end_toggle
@add_toggle_python
@snippet samples/python/tutorial_code/ShapeDescriptors/bounding_rects_circles/generalContours_demo1.py forContour
@end_toggle
- Display the results: create a new window "Contours" and show everything we added to drawings on it.
@add_toggle_cpp
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp showDrawings
@end_toggle
@add_toggle_java
@snippet samples/java/tutorial_code/ShapeDescriptors/bounding_rects_circles/GeneralContoursDemo1.java showDrawings
@end_toggle
@add_toggle_python
@snippet samples/python/tutorial_code/ShapeDescriptors/bounding_rects_circles/generalContours_demo1.py showDrawings
@end_toggle
Result Result
------ ------
......
...@@ -15,9 +15,23 @@ Theory ...@@ -15,9 +15,23 @@ Theory
Code Code
---- ----
@add_toggle_cpp
This tutorial code's is shown lines below. You can also download it from This tutorial code's is shown lines below. You can also download it from
[here](https://github.com/opencv/opencv/tree/3.4/samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo2.cpp) [here](https://github.com/opencv/opencv/tree/3.4/samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo2.cpp)
@include samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo2.cpp @include samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo2.cpp
@end_toggle
@add_toggle_java
This tutorial code's is shown lines below. You can also download it from
[here](https://github.com/opencv/opencv/tree/3.4/samples/java/tutorial_code/ShapeDescriptors/bounding_rotated_ellipses/GeneralContoursDemo2.java)
@include samples/java/tutorial_code/ShapeDescriptors/bounding_rotated_ellipses/GeneralContoursDemo2.java
@end_toggle
@add_toggle_python
This tutorial code's is shown lines below. You can also download it from
[here](https://github.com/opencv/opencv/tree/3.4/samples/python/tutorial_code/ShapeDescriptors/bounding_rotated_ellipses/generalContours_demo2.py)
@include samples/python/tutorial_code/ShapeDescriptors/bounding_rotated_ellipses/generalContours_demo2.py
@end_toggle
Explanation Explanation
----------- -----------
......
...@@ -15,9 +15,23 @@ Theory ...@@ -15,9 +15,23 @@ Theory
Code Code
---- ----
@add_toggle_cpp
This tutorial code's is shown lines below. You can also download it from This tutorial code's is shown lines below. You can also download it from
[here](https://github.com/opencv/opencv/tree/3.4/samples/cpp/tutorial_code/ShapeDescriptors/findContours_demo.cpp) [here](https://github.com/opencv/opencv/tree/3.4/samples/cpp/tutorial_code/ShapeDescriptors/findContours_demo.cpp)
@include samples/cpp/tutorial_code/ShapeDescriptors/findContours_demo.cpp @include samples/cpp/tutorial_code/ShapeDescriptors/findContours_demo.cpp
@end_toggle
@add_toggle_java
This tutorial code's is shown lines below. You can also download it from
[here](https://github.com/opencv/opencv/tree/3.4/samples/java/tutorial_code/ShapeDescriptors/find_contours/FindContoursDemo.java)
@include samples/java/tutorial_code/ShapeDescriptors/find_contours/FindContoursDemo.java
@end_toggle
@add_toggle_python
This tutorial code's is shown lines below. You can also download it from
[here](https://github.com/opencv/opencv/tree/3.4/samples/python/tutorial_code/ShapeDescriptors/find_contours/findContours_demo.py)
@include samples/python/tutorial_code/ShapeDescriptors/find_contours/findContours_demo.py
@end_toggle
Explanation Explanation
----------- -----------
......
...@@ -14,10 +14,23 @@ Theory ...@@ -14,10 +14,23 @@ Theory
Code Code
---- ----
@add_toggle_cpp
This tutorial code's is shown lines below. You can also download it from This tutorial code's is shown lines below. You can also download it from
[here](https://github.com/opencv/opencv/tree/3.4/samples/cpp/tutorial_code/ShapeDescriptors/hull_demo.cpp) [here](https://github.com/opencv/opencv/tree/3.4/samples/cpp/tutorial_code/ShapeDescriptors/hull_demo.cpp)
@include samples/cpp/tutorial_code/ShapeDescriptors/hull_demo.cpp @include samples/cpp/tutorial_code/ShapeDescriptors/hull_demo.cpp
@end_toggle
@add_toggle_java
This tutorial code's is shown lines below. You can also download it from
[here](https://github.com/opencv/opencv/tree/3.4/samples/java/tutorial_code/ShapeDescriptors/hull/HullDemo.java)
@include samples/java/tutorial_code/ShapeDescriptors/hull/HullDemo.java
@end_toggle
@add_toggle_python
This tutorial code's is shown lines below. You can also download it from
[here](https://github.com/opencv/opencv/tree/3.4/samples/python/tutorial_code/ShapeDescriptors/hull/hull_demo.py)
@include samples/python/tutorial_code/ShapeDescriptors/hull/hull_demo.py
@end_toggle
Explanation Explanation
----------- -----------
......
...@@ -16,9 +16,23 @@ Theory ...@@ -16,9 +16,23 @@ Theory
Code Code
---- ----
@add_toggle_cpp
This tutorial code's is shown lines below. You can also download it from This tutorial code's is shown lines below. You can also download it from
[here](https://github.com/opencv/opencv/tree/3.4/samples/cpp/tutorial_code/ShapeDescriptors/moments_demo.cpp) [here](https://github.com/opencv/opencv/tree/3.4/samples/cpp/tutorial_code/ShapeDescriptors/moments_demo.cpp)
@include samples/cpp/tutorial_code/ShapeDescriptors/moments_demo.cpp @include samples/cpp/tutorial_code/ShapeDescriptors/moments_demo.cpp
@end_toggle
@add_toggle_java
This tutorial code's is shown lines below. You can also download it from
[here](https://github.com/opencv/opencv/tree/3.4/samples/java/tutorial_code/ShapeDescriptors/moments/MomentsDemo.java)
@include samples/java/tutorial_code/ShapeDescriptors/moments/MomentsDemo.java
@end_toggle
@add_toggle_python
This tutorial code's is shown lines below. You can also download it from
[here](https://github.com/opencv/opencv/tree/3.4/samples/python/tutorial_code/ShapeDescriptors/moments/moments_demo.py)
@include samples/python/tutorial_code/ShapeDescriptors/moments/moments_demo.py
@end_toggle
Explanation Explanation
----------- -----------
......
...@@ -14,9 +14,23 @@ Theory ...@@ -14,9 +14,23 @@ Theory
Code Code
---- ----
@add_toggle_cpp
This tutorial code's is shown lines below. You can also download it from This tutorial code's is shown lines below. You can also download it from
[here](https://github.com/opencv/opencv/tree/3.4/samples/cpp/tutorial_code/ShapeDescriptors/pointPolygonTest_demo.cpp) [here](https://github.com/opencv/opencv/tree/3.4/samples/cpp/tutorial_code/ShapeDescriptors/pointPolygonTest_demo.cpp)
@include samples/cpp/tutorial_code/ShapeDescriptors/pointPolygonTest_demo.cpp @include samples/cpp/tutorial_code/ShapeDescriptors/pointPolygonTest_demo.cpp
@end_toggle
@add_toggle_java
This tutorial code's is shown lines below. You can also download it from
[here](https://github.com/opencv/opencv/tree/3.4/samples/java/tutorial_code/ShapeDescriptors/point_polygon_test/PointPolygonTestDemo.java)
@include samples/java/tutorial_code/ShapeDescriptors/point_polygon_test/PointPolygonTestDemo.java
@end_toggle
@add_toggle_python
This tutorial code's is shown lines below. You can also download it from
[here](https://github.com/opencv/opencv/tree/3.4/samples/python/tutorial_code/ShapeDescriptors/point_polygon_test/pointPolygonTest_demo.py)
@include samples/python/tutorial_code/ShapeDescriptors/point_polygon_test/pointPolygonTest_demo.py
@end_toggle
Explanation Explanation
----------- -----------
......
...@@ -225,6 +225,8 @@ In this section you will learn about the image processing (manipulation) functio ...@@ -225,6 +225,8 @@ In this section you will learn about the image processing (manipulation) functio
- @subpage tutorial_find_contours - @subpage tutorial_find_contours
*Languages:* C++, Java, Python
*Compatibility:* \> OpenCV 2.0 *Compatibility:* \> OpenCV 2.0
*Author:* Ana Huamán *Author:* Ana Huamán
...@@ -233,6 +235,8 @@ In this section you will learn about the image processing (manipulation) functio ...@@ -233,6 +235,8 @@ In this section you will learn about the image processing (manipulation) functio
- @subpage tutorial_hull - @subpage tutorial_hull
*Languages:* C++, Java, Python
*Compatibility:* \> OpenCV 2.0 *Compatibility:* \> OpenCV 2.0
*Author:* Ana Huamán *Author:* Ana Huamán
...@@ -241,6 +245,8 @@ In this section you will learn about the image processing (manipulation) functio ...@@ -241,6 +245,8 @@ In this section you will learn about the image processing (manipulation) functio
- @subpage tutorial_bounding_rects_circles - @subpage tutorial_bounding_rects_circles
*Languages:* C++, Java, Python
*Compatibility:* \> OpenCV 2.0 *Compatibility:* \> OpenCV 2.0
*Author:* Ana Huamán *Author:* Ana Huamán
...@@ -249,6 +255,8 @@ In this section you will learn about the image processing (manipulation) functio ...@@ -249,6 +255,8 @@ In this section you will learn about the image processing (manipulation) functio
- @subpage tutorial_bounding_rotated_ellipses - @subpage tutorial_bounding_rotated_ellipses
*Languages:* C++, Java, Python
*Compatibility:* \> OpenCV 2.0 *Compatibility:* \> OpenCV 2.0
*Author:* Ana Huamán *Author:* Ana Huamán
...@@ -257,6 +265,8 @@ In this section you will learn about the image processing (manipulation) functio ...@@ -257,6 +265,8 @@ In this section you will learn about the image processing (manipulation) functio
- @subpage tutorial_moments - @subpage tutorial_moments
*Languages:* C++, Java, Python
*Compatibility:* \> OpenCV 2.0 *Compatibility:* \> OpenCV 2.0
*Author:* Ana Huamán *Author:* Ana Huamán
...@@ -265,6 +275,8 @@ In this section you will learn about the image processing (manipulation) functio ...@@ -265,6 +275,8 @@ In this section you will learn about the image processing (manipulation) functio
- @subpage tutorial_point_polygon_test - @subpage tutorial_point_polygon_test
*Languages:* C++, Java, Python
*Compatibility:* \> OpenCV 2.0 *Compatibility:* \> OpenCV 2.0
*Author:* Ana Huamán *Author:* Ana Huamán
......
...@@ -12,9 +12,8 @@ ...@@ -12,9 +12,8 @@
using namespace cv; using namespace cv;
using namespace std; using namespace std;
Mat src; Mat src_gray; Mat src_gray;
int thresh = 100; int thresh = 100;
int max_thresh = 255;
RNG rng(12345); RNG rng(12345);
/// Function header /// Function header
...@@ -25,34 +24,31 @@ void thresh_callback(int, void* ); ...@@ -25,34 +24,31 @@ void thresh_callback(int, void* );
*/ */
int main( int argc, char** argv ) int main( int argc, char** argv )
{ {
/// Load source image /// Load source image
String imageName("../data/happyfish.jpg"); // by default CommandLineParser parser( argc, argv, "{@input | ../data/HappyFish.jpg | input image}" );
if (argc > 1) Mat src = imread( parser.get<String>( "@input" ) );
{ if( src.empty() )
imageName = argv[1]; {
} cout << "Could not open or find the image!\n" << endl;
src = imread(imageName, IMREAD_COLOR); cout << "Usage: " << argv[0] << " <Input image>" << endl;
return -1;
}
if (src.empty()) /// Convert image to gray and blur it
{ cvtColor( src, src_gray, COLOR_BGR2GRAY );
cerr << "No image supplied ..." << endl; blur( src_gray, src_gray, Size(3,3) );
return -1;
}
/// Convert image to gray and blur it /// Create Window
cvtColor( src, src_gray, COLOR_BGR2GRAY ); const char* source_window = "Source";
blur( src_gray, src_gray, Size(3,3) ); namedWindow( source_window );
imshow( source_window, src );
/// Create Window const int max_thresh = 255;
const char* source_window = "Source"; createTrackbar( "Canny thresh:", source_window, &thresh, max_thresh, thresh_callback );
namedWindow( source_window, WINDOW_AUTOSIZE ); thresh_callback( 0, 0 );
imshow( source_window, src );
createTrackbar( " Canny thresh:", "Source", &thresh, max_thresh, thresh_callback ); waitKey();
thresh_callback( 0, 0 ); return 0;
waitKey(0);
return(0);
} }
/** /**
...@@ -60,24 +56,23 @@ int main( int argc, char** argv ) ...@@ -60,24 +56,23 @@ int main( int argc, char** argv )
*/ */
void thresh_callback(int, void* ) void thresh_callback(int, void* )
{ {
Mat canny_output; /// Detect edges using Canny
vector<vector<Point> > contours; Mat canny_output;
vector<Vec4i> hierarchy; Canny( src_gray, canny_output, thresh, thresh*2 );
/// Detect edges using canny /// Find contours
Canny( src_gray, canny_output, thresh, thresh*2, 3 ); vector<vector<Point> > contours;
/// Find contours vector<Vec4i> hierarchy;
findContours( canny_output, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0) ); findContours( canny_output, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE );
/// Draw contours /// Draw contours
Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3 ); Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3 );
for( size_t i = 0; i< contours.size(); i++ ) for( size_t i = 0; i< contours.size(); i++ )
{ {
Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) ); Scalar color = Scalar( rng.uniform(0, 256), rng.uniform(0,256), rng.uniform(0,256) );
drawContours( drawing, contours, (int)i, color, 2, 8, hierarchy, 0, Point() ); drawContours( drawing, contours, (int)i, color, 2, LINE_8, hierarchy, 0 );
} }
/// Show in a window /// Show in a window
namedWindow( "Contours", WINDOW_AUTOSIZE ); imshow( "Contours", drawing );
imshow( "Contours", drawing );
} }
...@@ -12,9 +12,8 @@ ...@@ -12,9 +12,8 @@
using namespace cv; using namespace cv;
using namespace std; using namespace std;
Mat src; Mat src_gray; Mat src_gray;
int thresh = 100; int thresh = 100;
int max_thresh = 255;
RNG rng(12345); RNG rng(12345);
/// Function header /// Function header
...@@ -25,42 +24,37 @@ void thresh_callback(int, void* ); ...@@ -25,42 +24,37 @@ void thresh_callback(int, void* );
*/ */
int main( int argc, char** argv ) int main( int argc, char** argv )
{ {
//![setup] //! [setup]
/// Load source image /// Load source image
CommandLineParser parser( argc, argv, "{@input | ../data/stuff.jpg | input image}" ); CommandLineParser parser( argc, argv, "{@input | ../data/stuff.jpg | input image}" );
src = imread( parser.get<String>( "@input" ), IMREAD_COLOR ); Mat src = imread( parser.get<String>( "@input" ) );
if( src.empty() ) if( src.empty() )
{ {
cout << "Could not open or find the image!\n" << endl; cout << "Could not open or find the image!\n" << endl;
cout << "usage: " << argv[0] << " <Input image>" << endl; cout << "usage: " << argv[0] << " <Input image>" << endl;
return -1; return -1;
} }
/// Convert image to gray and blur it /// Convert image to gray and blur it
cvtColor( src, src_gray, COLOR_BGR2GRAY ); cvtColor( src, src_gray, COLOR_BGR2GRAY );
blur( src_gray, src_gray, Size(3,3) ); blur( src_gray, src_gray, Size(3,3) );
//![setup] //! [setup]
//![createWindow] //! [createWindow]
/// Create Window /// Create Window
const char* source_window = "Source"; const char* source_window = "Source";
namedWindow( source_window, WINDOW_AUTOSIZE ); namedWindow( source_window );
imshow( source_window, src ); imshow( source_window, src );
//![createWindow] //! [createWindow]
//![taskbar] //! [trackbar]
createTrackbar( " Threshold:", "Source", &thresh, max_thresh, thresh_callback ); const int max_thresh = 255;
//![taskbar] createTrackbar( "Canny thresh:", source_window, &thresh, max_thresh, thresh_callback );
thresh_callback( 0, 0 );
//![callback00] //! [trackbar]
thresh_callback( 0, 0 );
//![callback00] waitKey();
return 0;
//![waitForIt]
waitKey(0);
//![waitForIt]
return(0);
} }
/** /**
...@@ -68,53 +62,50 @@ int main( int argc, char** argv ) ...@@ -68,53 +62,50 @@ int main( int argc, char** argv )
*/ */
void thresh_callback(int, void* ) void thresh_callback(int, void* )
{ {
Mat threshold_output; //! [Canny]
vector<vector<Point> > contours; /// Detect edges using Canny
vector<Vec4i> hierarchy; Mat canny_output;
Canny( src_gray, canny_output, thresh, thresh*2 );
//![threshold] //! [Canny]
/// Detect edges using Threshold
threshold( src_gray, threshold_output, thresh, 255, THRESH_BINARY ); //! [findContours]
//![threshold] /// Find contours
vector<vector<Point> > contours;
//![findContours] findContours( canny_output, contours, RETR_TREE, CHAIN_APPROX_SIMPLE );
/// Find contours //! [findContours]
findContours( threshold_output, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0) );
//![findContours] //! [allthework]
/// Approximate contours to polygons + get bounding rects and circles
/// Approximate contours to polygons + get bounding rects and circles vector<vector<Point> > contours_poly( contours.size() );
vector<vector<Point> > contours_poly( contours.size() ); vector<Rect> boundRect( contours.size() );
vector<Rect> boundRect( contours.size() ); vector<Point2f>centers( contours.size() );
vector<Point2f>center( contours.size() ); vector<float>radius( contours.size() );
vector<float>radius( contours.size() );
for( size_t i = 0; i < contours.size(); i++ )
//![allthework] {
for( size_t i = 0; i < contours.size(); i++ ) approxPolyDP( contours[i], contours_poly[i], 3, true );
{ boundRect[i] = boundingRect( contours_poly[i] );
approxPolyDP( contours[i], contours_poly[i], 3, true ); minEnclosingCircle( contours_poly[i], centers[i], radius[i] );
boundRect[i] = boundingRect( contours_poly[i] ); }
minEnclosingCircle( contours_poly[i], center[i], radius[i] ); //! [allthework]
}
//![allthework] //! [zeroMat]
Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3 );
//![zeroMat] //! [zeroMat]
/// Draw polygonal contour + bonding rects + circles
Mat drawing = Mat::zeros( threshold_output.size(), CV_8UC3 ); //! [forContour]
//![zeroMat] /// Draw polygonal contour + bonding rects + circles
for( size_t i = 0; i< contours.size(); i++ )
//![forContour] {
for( size_t i = 0; i< contours.size(); i++ ) Scalar color = Scalar( rng.uniform(0, 256), rng.uniform(0,256), rng.uniform(0,256) );
{ drawContours( drawing, contours_poly, (int)i, color );
Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) ); rectangle( drawing, boundRect[i].tl(), boundRect[i].br(), color, 2 );
drawContours( drawing, contours_poly, (int)i, color, 1, 8, vector<Vec4i>(), 0, Point() ); circle( drawing, centers[i], (int)radius[i], color, 2 );
rectangle( drawing, boundRect[i].tl(), boundRect[i].br(), color, 2, 8, 0 ); }
circle( drawing, center[i], (int)radius[i], color, 2, 8, 0 ); //! [forContour]
}
//![forContour] //! [showDrawings]
/// Show in a window
//![showDrawings] imshow( "Contours", drawing );
/// Show in a window //! [showDrawings]
namedWindow( "Contours", WINDOW_AUTOSIZE );
imshow( "Contours", drawing );
//![showDrawings]
} }
...@@ -12,9 +12,8 @@ ...@@ -12,9 +12,8 @@
using namespace cv; using namespace cv;
using namespace std; using namespace std;
Mat src; Mat src_gray; Mat src_gray;
int thresh = 100; int thresh = 100;
int max_thresh = 255;
RNG rng(12345); RNG rng(12345);
/// Function header /// Function header
...@@ -25,30 +24,31 @@ void thresh_callback(int, void* ); ...@@ -25,30 +24,31 @@ void thresh_callback(int, void* );
*/ */
int main( int argc, char** argv ) int main( int argc, char** argv )
{ {
/// Load source image and convert it to gray /// Load source image and convert it to gray
CommandLineParser parser( argc, argv, "{@input | ../data/stuff.jpg | input image}" ); CommandLineParser parser( argc, argv, "{@input | ../data/stuff.jpg | input image}" );
src = imread( parser.get<String>( "@input" ), IMREAD_COLOR ); Mat src = imread( parser.get<String>( "@input" ) );
if( src.empty() ) if( src.empty() )
{ {
cout << "Could not open or find the image!\n" << endl; cout << "Could not open or find the image!\n" << endl;
cout << "Usage: " << argv[0] << " <Input image>" << endl; cout << "Usage: " << argv[0] << " <Input image>" << endl;
return -1; return -1;
} }
/// Convert image to gray and blur it /// Convert image to gray and blur it
cvtColor( src, src_gray, COLOR_BGR2GRAY ); cvtColor( src, src_gray, COLOR_BGR2GRAY );
blur( src_gray, src_gray, Size(3,3) ); blur( src_gray, src_gray, Size(3,3) );
/// Create Window /// Create Window
const char* source_window = "Source"; const char* source_window = "Source";
namedWindow( source_window, WINDOW_AUTOSIZE ); namedWindow( source_window );
imshow( source_window, src ); imshow( source_window, src );
createTrackbar( " Threshold:", "Source", &thresh, max_thresh, thresh_callback ); const int max_thresh = 255;
thresh_callback( 0, 0 ); createTrackbar( "Canny thresh:", source_window, &thresh, max_thresh, thresh_callback );
thresh_callback( 0, 0 );
waitKey(0); waitKey();
return(0); return 0;
} }
/** /**
...@@ -56,41 +56,43 @@ int main( int argc, char** argv ) ...@@ -56,41 +56,43 @@ int main( int argc, char** argv )
*/ */
void thresh_callback(int, void* ) void thresh_callback(int, void* )
{ {
Mat threshold_output; /// Detect edges using Canny
vector<vector<Point> > contours; Mat canny_output;
vector<Vec4i> hierarchy; Canny( src_gray, canny_output, thresh, thresh*2 );
/// Find contours
vector<vector<Point> > contours;
findContours( canny_output, contours, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0) );
/// Detect edges using Threshold /// Find the rotated rectangles and ellipses for each contour
threshold( src_gray, threshold_output, thresh, 255, THRESH_BINARY ); vector<RotatedRect> minRect( contours.size() );
/// Find contours vector<RotatedRect> minEllipse( contours.size() );
findContours( threshold_output, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0) ); for( size_t i = 0; i < contours.size(); i++ )
{
/// Find the rotated rectangles and ellipses for each contour minRect[i] = minAreaRect( contours[i] );
vector<RotatedRect> minRect( contours.size() ); if( contours[i].size() > 5 )
vector<RotatedRect> minEllipse( contours.size() ); {
minEllipse[i] = fitEllipse( contours[i] );
for( size_t i = 0; i < contours.size(); i++ ) }
{ minRect[i] = minAreaRect( contours[i] ); }
if( contours[i].size() > 5 )
{ minEllipse[i] = fitEllipse( contours[i] ); }
}
/// Draw contours + rotated rects + ellipses /// Draw contours + rotated rects + ellipses
Mat drawing = Mat::zeros( threshold_output.size(), CV_8UC3 ); Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3 );
for( size_t i = 0; i< contours.size(); i++ ) for( size_t i = 0; i< contours.size(); i++ )
{ {
Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) ); Scalar color = Scalar( rng.uniform(0, 256), rng.uniform(0,256), rng.uniform(0,256) );
// contour // contour
drawContours( drawing, contours, (int)i, color, 1, 8, vector<Vec4i>(), 0, Point() ); drawContours( drawing, contours, (int)i, color );
// ellipse // ellipse
ellipse( drawing, minEllipse[i], color, 2, 8 ); ellipse( drawing, minEllipse[i], color, 2 );
// rotated rectangle // rotated rectangle
Point2f rect_points[4]; minRect[i].points( rect_points ); Point2f rect_points[4];
for( int j = 0; j < 4; j++ ) minRect[i].points( rect_points );
line( drawing, rect_points[j], rect_points[(j+1)%4], color, 1, 8 ); for ( int j = 0; j < 4; j++ )
} {
line( drawing, rect_points[j], rect_points[(j+1)%4], color );
}
}
/// Show in a window /// Show in a window
namedWindow( "Contours", WINDOW_AUTOSIZE ); imshow( "Contours", drawing );
imshow( "Contours", drawing );
} }
...@@ -12,9 +12,8 @@ ...@@ -12,9 +12,8 @@
using namespace cv; using namespace cv;
using namespace std; using namespace std;
Mat src; Mat src_gray; Mat src_gray;
int thresh = 100; int thresh = 100;
int max_thresh = 255;
RNG rng(12345); RNG rng(12345);
/// Function header /// Function header
...@@ -25,30 +24,31 @@ void thresh_callback(int, void* ); ...@@ -25,30 +24,31 @@ void thresh_callback(int, void* );
*/ */
int main( int argc, char** argv ) int main( int argc, char** argv )
{ {
/// Load source image and convert it to gray /// Load source image and convert it to gray
CommandLineParser parser( argc, argv, "{@input | ../data/stuff.jpg | input image}" ); CommandLineParser parser( argc, argv, "{@input | ../data/stuff.jpg | input image}" );
src = imread( parser.get<String>( "@input" ), IMREAD_COLOR ); Mat src = imread( parser.get<String>( "@input" ) );
if( src.empty() ) if( src.empty() )
{ {
cout << "Could not open or find the image!\n" << endl; cout << "Could not open or find the image!\n" << endl;
cout << "Usage: " << argv[0] << " <Input image>" << endl; cout << "Usage: " << argv[0] << " <Input image>" << endl;
return -1; return -1;
} }
/// Convert image to gray and blur it /// Convert image to gray and blur it
cvtColor( src, src_gray, COLOR_BGR2GRAY ); cvtColor( src, src_gray, COLOR_BGR2GRAY );
blur( src_gray, src_gray, Size(3,3) ); blur( src_gray, src_gray, Size(3,3) );
/// Create Window /// Create Window
const char* source_window = "Source"; const char* source_window = "Source";
namedWindow( source_window, WINDOW_AUTOSIZE ); namedWindow( source_window );
imshow( source_window, src ); imshow( source_window, src );
createTrackbar( " Threshold:", "Source", &thresh, max_thresh, thresh_callback ); const int max_thresh = 255;
thresh_callback( 0, 0 ); createTrackbar( "Canny thresh:", source_window, &thresh, max_thresh, thresh_callback );
thresh_callback( 0, 0 );
waitKey(0); waitKey();
return(0); return 0;
} }
/** /**
...@@ -56,31 +56,30 @@ int main( int argc, char** argv ) ...@@ -56,31 +56,30 @@ int main( int argc, char** argv )
*/ */
void thresh_callback(int, void* ) void thresh_callback(int, void* )
{ {
Mat threshold_output; /// Detect edges using Canny
vector<vector<Point> > contours; Mat canny_output;
vector<Vec4i> hierarchy; Canny( src_gray, canny_output, thresh, thresh*2 );
/// Detect edges using Threshold /// Find contours
threshold( src_gray, threshold_output, thresh, 255, THRESH_BINARY ); vector<vector<Point> > contours;
findContours( canny_output, contours, RETR_TREE, CHAIN_APPROX_SIMPLE );
/// Find contours /// Find the convex hull object for each contour
findContours( threshold_output, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0) ); vector<vector<Point> >hull( contours.size() );
for( size_t i = 0; i < contours.size(); i++ )
{
convexHull( contours[i], hull[i] );
}
/// Find the convex hull object for each contour /// Draw contours + hull results
vector<vector<Point> >hull( contours.size() ); Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3 );
for( size_t i = 0; i < contours.size(); i++ ) for( size_t i = 0; i< contours.size(); i++ )
{ convexHull( contours[i], hull[i], false ); } {
Scalar color = Scalar( rng.uniform(0, 256), rng.uniform(0,256), rng.uniform(0,256) );
drawContours( drawing, contours, (int)i, color );
drawContours( drawing, hull, (int)i, color );
}
/// Draw contours + hull results /// Show in a window
Mat drawing = Mat::zeros( threshold_output.size(), CV_8UC3 ); imshow( "Hull demo", drawing );
for( size_t i = 0; i< contours.size(); i++ )
{
Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
drawContours( drawing, contours, (int)i, color, 1, 8, vector<Vec4i>(), 0, Point() );
drawContours( drawing, hull, (int)i, color, 1, 8, vector<Vec4i>(), 0, Point() );
}
/// Show in a window
namedWindow( "Hull demo", WINDOW_AUTOSIZE );
imshow( "Hull demo", drawing );
} }
...@@ -8,13 +8,13 @@ ...@@ -8,13 +8,13 @@
#include "opencv2/highgui.hpp" #include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp" #include "opencv2/imgproc.hpp"
#include <iostream> #include <iostream>
#include <iomanip>
using namespace cv; using namespace cv;
using namespace std; using namespace std;
Mat src; Mat src_gray; Mat src_gray;
int thresh = 100; int thresh = 100;
int max_thresh = 255;
RNG rng(12345); RNG rng(12345);
/// Function header /// Function header
...@@ -25,31 +25,32 @@ void thresh_callback(int, void* ); ...@@ -25,31 +25,32 @@ void thresh_callback(int, void* );
*/ */
int main( int argc, char** argv ) int main( int argc, char** argv )
{ {
/// Load source image and convert it to gray /// Load source image
CommandLineParser parser( argc, argv, "{@input | ../data/stuff.jpg | input image}" ); CommandLineParser parser( argc, argv, "{@input | ../data/stuff.jpg | input image}" );
src = imread( parser.get<String>( "@input" ), IMREAD_COLOR ); Mat src = imread( parser.get<String>( "@input" ) );
if( src.empty() ) if( src.empty() )
{ {
cout << "Could not open or find the image!\n" << endl; cout << "Could not open or find the image!\n" << endl;
cout << "usage: " << argv[0] << " <Input image>" << endl; cout << "usage: " << argv[0] << " <Input image>" << endl;
exit(0); return -1;
} }
/// Convert image to gray and blur it /// Convert image to gray and blur it
cvtColor( src, src_gray, COLOR_BGR2GRAY ); cvtColor( src, src_gray, COLOR_BGR2GRAY );
blur( src_gray, src_gray, Size(3,3) ); blur( src_gray, src_gray, Size(3,3) );
/// Create Window /// Create Window
const char* source_window = "Source"; const char* source_window = "Source";
namedWindow( source_window, WINDOW_AUTOSIZE ); namedWindow( source_window );
imshow( source_window, src ); imshow( source_window, src );
createTrackbar( " Canny thresh:", "Source", &thresh, max_thresh, thresh_callback ); const int max_thresh = 255;
thresh_callback( 0, 0 ); createTrackbar( "Canny thresh:", source_window, &thresh, max_thresh, thresh_callback );
thresh_callback( 0, 0 );
waitKey(0);
return(0); waitKey();
return 0;
} }
/** /**
...@@ -57,44 +58,47 @@ int main( int argc, char** argv ) ...@@ -57,44 +58,47 @@ int main( int argc, char** argv )
*/ */
void thresh_callback(int, void* ) void thresh_callback(int, void* )
{ {
Mat canny_output; /// Detect edges using canny
vector<vector<Point> > contours; Mat canny_output;
Canny( src_gray, canny_output, thresh, thresh*2, 3 );
/// Detect edges using canny /// Find contours
Canny( src_gray, canny_output, thresh, thresh*2, 3 ); vector<vector<Point> > contours;
/// Find contours findContours( canny_output, contours, RETR_TREE, CHAIN_APPROX_SIMPLE );
findContours( canny_output, contours, RETR_TREE, CHAIN_APPROX_SIMPLE );
/// Get the moments
/// Get the moments vector<Moments> mu(contours.size() );
vector<Moments> mu(contours.size() ); for( size_t i = 0; i < contours.size(); i++ )
for( size_t i = 0; i < contours.size(); i++ ) {
{ mu[i] = moments( contours[i], false ); } mu[i] = moments( contours[i] );
}
/// Get the mass centers:
vector<Point2f> mc( contours.size() ); /// Get the mass centers
for( size_t i = 0; i < contours.size(); i++ ) vector<Point2f> mc( contours.size() );
{ mc[i] = Point2f( static_cast<float>(mu[i].m10/mu[i].m00) , static_cast<float>(mu[i].m01/mu[i].m00) ); } for( size_t i = 0; i < contours.size(); i++ )
{
/// Draw contours //add 1e-5 to avoid division by zero
Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3 ); mc[i] = Point2f( static_cast<float>(mu[i].m10 / (mu[i].m00 + 1e-5)),
for( size_t i = 0; i< contours.size(); i++ ) static_cast<float>(mu[i].m01 / (mu[i].m00 + 1e-5)) );
{ cout << "mc[" << i << "]=" << mc[i] << endl;
Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) ); }
drawContours( drawing, contours, (int)i, color, 2, LINE_8 );
circle( drawing, mc[i], 4, color, -1, 8, 0 ); /// Draw contours
} Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3 );
for( size_t i = 0; i< contours.size(); i++ )
/// Show in a window {
namedWindow( "Contours", WINDOW_AUTOSIZE ); Scalar color = Scalar( rng.uniform(0, 256), rng.uniform(0,256), rng.uniform(0,256) );
imshow( "Contours", drawing ); drawContours( drawing, contours, (int)i, color, 2 );
circle( drawing, mc[i], 4, color, -1 );
/// Calculate the area with the moments 00 and compare with the result of the OpenCV function }
printf("\t Info: Area and Contour Length \n");
for( size_t i = 0; i< contours.size(); i++ ) /// Show in a window
{ imshow( "Contours", drawing );
printf(" * Contour[%d] - Area (M_00) = %.2f - Area OpenCV: %.2f - Length: %.2f \n", (int)i, mu[i].m00, contourArea(contours[i]), arcLength( contours[i], true ) );
Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) ); /// Calculate the area with the moments 00 and compare with the result of the OpenCV function
drawContours( drawing, contours, (int)i, color, 2, LINE_8 ); cout << "\t Info: Area and Contour Length \n";
circle( drawing, mc[i], 4, color, -1, 8, 0 ); for( size_t i = 0; i < contours.size(); i++ )
} {
cout << " * Contour[" << i << "] - Area (M_00) = " << std::fixed << std::setprecision(2) << mu[i].m00
<< " - Area OpenCV: " << contourArea(contours[i]) << " - Length: " << arcLength( contours[i], true ) << endl;
}
} }
...@@ -16,60 +16,71 @@ using namespace std; ...@@ -16,60 +16,71 @@ using namespace std;
*/ */
int main( void ) int main( void )
{ {
/// Create an image /// Create an image
const int r = 100; const int r = 100;
Mat src = Mat::zeros( Size( 4*r, 4*r ), CV_8UC1 ); Mat src = Mat::zeros( Size( 4*r, 4*r ), CV_8U );
/// Create a sequence of points to make a contour: /// Create a sequence of points to make a contour
vector<Point2f> vert(6); vector<Point2f> vert(6);
vert[0] = Point( 3*r/2, static_cast<int>(1.34*r) );
vert[1] = Point( 1*r, 2*r );
vert[2] = Point( 3*r/2, static_cast<int>(2.866*r) );
vert[3] = Point( 5*r/2, static_cast<int>(2.866*r) );
vert[4] = Point( 3*r, 2*r );
vert[5] = Point( 5*r/2, static_cast<int>(1.34*r) );
vert[0] = Point( 3*r/2, static_cast<int>(1.34*r) ); /// Draw it in src
vert[1] = Point( 1*r, 2*r ); for( int i = 0; i < 6; i++ )
vert[2] = Point( 3*r/2, static_cast<int>(2.866*r) ); {
vert[3] = Point( 5*r/2, static_cast<int>(2.866*r) ); line( src, vert[i], vert[(i+1)%6], Scalar( 255 ), 3 );
vert[4] = Point( 3*r, 2*r ); }
vert[5] = Point( 5*r/2, static_cast<int>(1.34*r) );
/// Draw it in src /// Get the contours
for( int j = 0; j < 6; j++ ) vector<vector<Point> > contours;
{ line( src, vert[j], vert[(j+1)%6], Scalar( 255 ), 3, 8 ); } findContours( src, contours, RETR_TREE, CHAIN_APPROX_SIMPLE);
/// Get the contours /// Calculate the distances to the contour
vector<vector<Point> > contours; Mat raw_dist( src.size(), CV_32F );
for( int i = 0; i < src.rows; i++ )
{
for( int j = 0; j < src.cols; j++ )
{
raw_dist.at<float>(i,j) = (float)pointPolygonTest( contours[0], Point2f((float)j, (float)i), true );
}
}
findContours( src, contours, RETR_TREE, CHAIN_APPROX_SIMPLE); double minVal, maxVal;
minMaxLoc( raw_dist, &minVal, &maxVal );
minVal = abs(minVal);
maxVal = abs(maxVal);
/// Calculate the distances to the contour /// Depicting the distances graphically
Mat raw_dist( src.size(), CV_32FC1 ); Mat drawing = Mat::zeros( src.size(), CV_8UC3 );
for( int i = 0; i < src.rows; i++ )
for( int j = 0; j < src.rows; j++ ) {
{ for( int i = 0; i < src.cols; i++ ) for( int j = 0; j < src.cols; j++ )
{ raw_dist.at<float>(j,i) = (float)pointPolygonTest( contours[0], Point2f((float)i,(float)j), true ); } {
} if( raw_dist.at<float>(i,j) < 0 )
{
double minVal; double maxVal; drawing.at<Vec3b>(i,j)[0] = (uchar)(255 - abs(raw_dist.at<float>(i,j)) * 255 / minVal);
minMaxLoc( raw_dist, &minVal, &maxVal, 0, 0, Mat() ); }
minVal = abs(minVal); maxVal = abs(maxVal); else if( raw_dist.at<float>(i,j) > 0 )
{
/// Depicting the distances graphically drawing.at<Vec3b>(i,j)[2] = (uchar)(255 - raw_dist.at<float>(i,j) * 255 / maxVal);
Mat drawing = Mat::zeros( src.size(), CV_8UC3 ); }
for( int j = 0; j < src.rows; j++ )
{ for( int i = 0; i < src.cols; i++ )
{
if( raw_dist.at<float>(j,i) < 0 )
{ drawing.at<Vec3b>(j,i)[0] = (uchar)(255 - abs(raw_dist.at<float>(j,i))*255/minVal); }
else if( raw_dist.at<float>(j,i) > 0 )
{ drawing.at<Vec3b>(j,i)[2] = (uchar)(255 - raw_dist.at<float>(j,i)*255/maxVal); }
else else
{ drawing.at<Vec3b>(j,i)[0] = 255; drawing.at<Vec3b>(j,i)[1] = 255; drawing.at<Vec3b>(j,i)[2] = 255; } {
} drawing.at<Vec3b>(i,j)[0] = 255;
} drawing.at<Vec3b>(i,j)[1] = 255;
drawing.at<Vec3b>(i,j)[2] = 255;
}
}
}
/// Show your results /// Show your results
imshow( "Source", src ); imshow( "Source", src );
imshow( "Distance", drawing ); imshow( "Distance", drawing );
waitKey(0); waitKey();
return(0); return 0;
} }
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Image;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
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.MatOfPoint;
import org.opencv.core.MatOfPoint2f;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
class GeneralContours1 {
private Mat srcGray = new Mat();
private JFrame frame;
private JLabel imgSrcLabel;
private JLabel imgContoursLabel;
private static final int MAX_THRESHOLD = 255;
private int threshold = 100;
private Random rng = new Random(12345);
public GeneralContours1(String[] args) {
//! [setup]
/// Load source image
String filename = args.length > 0 ? args[0] : "../data/stuff.jpg";
Mat src = Imgcodecs.imread(filename);
if (src.empty()) {
System.err.println("Cannot read image: " + filename);
System.exit(0);
}
/// Convert image to gray and blur it
Imgproc.cvtColor(src, srcGray, Imgproc.COLOR_BGR2GRAY);
Imgproc.blur(srcGray, srcGray, new Size(3, 3));
//! [setup]
//! [createWindow]
// Create and set up the window.
frame = new JFrame("Creating Bounding boxes and circles for contours demo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Set up the content pane.
Image img = HighGui.toBufferedImage(src);
addComponentsToPane(frame.getContentPane(), img);
//! [createWindow]
// Use the content pane's default BorderLayout. No need for
// setLayout(new BorderLayout());
// Display the window.
frame.pack();
frame.setVisible(true);
update();
}
private void addComponentsToPane(Container pane, Image img) {
if (!(pane.getLayout() instanceof BorderLayout)) {
pane.add(new JLabel("Container doesn't use BorderLayout!"));
return;
}
JPanel sliderPanel = new JPanel();
sliderPanel.setLayout(new BoxLayout(sliderPanel, BoxLayout.PAGE_AXIS));
//! [trackbar]
sliderPanel.add(new JLabel("Canny threshold: "));
JSlider slider = new JSlider(0, MAX_THRESHOLD, threshold);
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();
threshold = source.getValue();
update();
}
});
//! [trackbar]
sliderPanel.add(slider);
pane.add(sliderPanel, BorderLayout.PAGE_START);
JPanel imgPanel = new JPanel();
imgSrcLabel = new JLabel(new ImageIcon(img));
imgPanel.add(imgSrcLabel);
Mat blackImg = Mat.zeros(srcGray.size(), CvType.CV_8U);
imgContoursLabel = new JLabel(new ImageIcon(HighGui.toBufferedImage(blackImg)));
imgPanel.add(imgContoursLabel);
pane.add(imgPanel, BorderLayout.CENTER);
}
private void update() {
//! [Canny]
/// Detect edges using Canny
Mat cannyOutput = new Mat();
Imgproc.Canny(srcGray, cannyOutput, threshold, threshold * 2);
//! [Canny]
//! [findContours]
/// Find contours
List<MatOfPoint> contours = new ArrayList<>();
Mat hierarchy = new Mat();
Imgproc.findContours(cannyOutput, contours, hierarchy, Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE);
//! [findContours]
//! [allthework]
/// Approximate contours to polygons + get bounding rects and circles
MatOfPoint2f[] contoursPoly = new MatOfPoint2f[contours.size()];
Rect[] boundRect = new Rect[contours.size()];
Point[] centers = new Point[contours.size()];
float[][] radius = new float[contours.size()][1];
for (int i = 0; i < contours.size(); i++) {
contoursPoly[i] = new MatOfPoint2f();
Imgproc.approxPolyDP(new MatOfPoint2f(contours.get(i).toArray()), contoursPoly[i], 3, true);
boundRect[i] = Imgproc.boundingRect(new MatOfPoint(contoursPoly[i].toArray()));
centers[i] = new Point();
Imgproc.minEnclosingCircle(contoursPoly[i], centers[i], radius[i]);
}
//! [allthework]
//! [zeroMat]
Mat drawing = Mat.zeros(cannyOutput.size(), CvType.CV_8UC3);
//! [zeroMat]
//! [forContour]
/// Draw polygonal contour + bonding rects + circles
List<MatOfPoint> contoursPolyList = new ArrayList<>(contoursPoly.length);
for (MatOfPoint2f poly : contoursPoly) {
contoursPolyList.add(new MatOfPoint(poly.toArray()));
}
for (int i = 0; i < contours.size(); i++) {
Scalar color = new Scalar(rng.nextInt(256), rng.nextInt(256), rng.nextInt(256));
Imgproc.drawContours(drawing, contoursPolyList, i, color);
Imgproc.rectangle(drawing, boundRect[i].tl(), boundRect[i].br(), color, 2);
Imgproc.circle(drawing, centers[i], (int) radius[i][0], color, 2);
}
//! [forContour]
//! [showDrawings]
/// Show in a window
imgContoursLabel.setIcon(new ImageIcon(HighGui.toBufferedImage(drawing)));
frame.repaint();
//! [showDrawings]
}
}
public class GeneralContoursDemo1 {
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 GeneralContours1(args);
}
});
}
}
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Image;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
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.MatOfPoint;
import org.opencv.core.MatOfPoint2f;
import org.opencv.core.Point;
import org.opencv.core.RotatedRect;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
class GeneralContours2 {
private Mat srcGray = new Mat();
private JFrame frame;
private JLabel imgSrcLabel;
private JLabel imgContoursLabel;
private static final int MAX_THRESHOLD = 255;
private int threshold = 100;
private Random rng = new Random(12345);
public GeneralContours2(String[] args) {
//! [setup]
/// Load source image
String filename = args.length > 0 ? args[0] : "../data/stuff.jpg";
Mat src = Imgcodecs.imread(filename);
if (src.empty()) {
System.err.println("Cannot read image: " + filename);
System.exit(0);
}
/// Convert image to gray and blur it
Imgproc.cvtColor(src, srcGray, Imgproc.COLOR_BGR2GRAY);
Imgproc.blur(srcGray, srcGray, new Size(3, 3));
//! [setup]
//! [createWindow]
// Create and set up the window.
frame = new JFrame("Creating Bounding rotated boxes and ellipses for contours demo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Set up the content pane.
Image img = HighGui.toBufferedImage(src);
addComponentsToPane(frame.getContentPane(), img);
//! [createWindow]
// Use the content pane's default BorderLayout. No need for
// setLayout(new BorderLayout());
// Display the window.
frame.pack();
frame.setVisible(true);
update();
}
private void addComponentsToPane(Container pane, Image img) {
if (!(pane.getLayout() instanceof BorderLayout)) {
pane.add(new JLabel("Container doesn't use BorderLayout!"));
return;
}
JPanel sliderPanel = new JPanel();
sliderPanel.setLayout(new BoxLayout(sliderPanel, BoxLayout.PAGE_AXIS));
//! [trackbar]
sliderPanel.add(new JLabel("Canny threshold: "));
JSlider slider = new JSlider(0, MAX_THRESHOLD, threshold);
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();
threshold = source.getValue();
update();
}
});
//! [trackbar]
sliderPanel.add(slider);
pane.add(sliderPanel, BorderLayout.PAGE_START);
JPanel imgPanel = new JPanel();
imgSrcLabel = new JLabel(new ImageIcon(img));
imgPanel.add(imgSrcLabel);
Mat blackImg = Mat.zeros(srcGray.size(), CvType.CV_8U);
imgContoursLabel = new JLabel(new ImageIcon(HighGui.toBufferedImage(blackImg)));
imgPanel.add(imgContoursLabel);
pane.add(imgPanel, BorderLayout.CENTER);
}
private void update() {
//! [Canny]
/// Detect edges using Canny
Mat cannyOutput = new Mat();
Imgproc.Canny(srcGray, cannyOutput, threshold, threshold * 2);
//! [Canny]
//! [findContours]
/// Find contours
List<MatOfPoint> contours = new ArrayList<>();
Mat hierarchy = new Mat();
Imgproc.findContours(cannyOutput, contours, hierarchy, Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE);
//! [findContours]
/// Find the rotated rectangles and ellipses for each contour
RotatedRect[] minRect = new RotatedRect[contours.size()];
RotatedRect[] minEllipse = new RotatedRect[contours.size()];
for (int i = 0; i < contours.size(); i++) {
minRect[i] = Imgproc.minAreaRect(new MatOfPoint2f(contours.get(i).toArray()));
minEllipse[i] = new RotatedRect();
if (contours.get(i).rows() > 5) {
minEllipse[i] = Imgproc.fitEllipse(new MatOfPoint2f(contours.get(i).toArray()));
}
}
//! [zeroMat]
/// Draw contours + rotated rects + ellipses
Mat drawing = Mat.zeros(cannyOutput.size(), CvType.CV_8UC3);
//! [zeroMat]
//! [forContour]
for (int i = 0; i < contours.size(); i++) {
Scalar color = new Scalar(rng.nextInt(256), rng.nextInt(256), rng.nextInt(256));
// contour
Imgproc.drawContours(drawing, contours, i, color);
// ellipse
Imgproc.ellipse(drawing, minEllipse[i], color, 2);
// rotated rectangle
Point[] rectPoints = new Point[4];
minRect[i].points(rectPoints);
for (int j = 0; j < 4; j++) {
Imgproc.line(drawing, rectPoints[j], rectPoints[(j+1) % 4], color);
}
}
//! [forContour]
//! [showDrawings]
/// Show in a window
imgContoursLabel.setIcon(new ImageIcon(HighGui.toBufferedImage(drawing)));
frame.repaint();
//! [showDrawings]
}
}
public class GeneralContoursDemo2 {
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 GeneralContours2(args);
}
});
}
}
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Image;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
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.MatOfPoint;
import org.opencv.core.Point;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
class FindContours {
private Mat srcGray = new Mat();
private JFrame frame;
private JLabel imgSrcLabel;
private JLabel imgContoursLabel;
private static final int MAX_THRESHOLD = 255;
private int threshold = 100;
private Random rng = new Random(12345);
public FindContours(String[] args) {
/// Load source image
String filename = args.length > 0 ? args[0] : "../data/HappyFish.jpg";
Mat src = Imgcodecs.imread(filename);
if (src.empty()) {
System.err.println("Cannot read image: " + filename);
System.exit(0);
}
/// Convert image to gray and blur it
Imgproc.cvtColor(src, srcGray, Imgproc.COLOR_BGR2GRAY);
Imgproc.blur(srcGray, srcGray, new Size(3, 3));
// Create and set up the window.
frame = new JFrame("Finding contours in your image 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);
update();
}
private void addComponentsToPane(Container pane, Image img) {
if (!(pane.getLayout() instanceof BorderLayout)) {
pane.add(new JLabel("Container doesn't use BorderLayout!"));
return;
}
JPanel sliderPanel = new JPanel();
sliderPanel.setLayout(new BoxLayout(sliderPanel, BoxLayout.PAGE_AXIS));
sliderPanel.add(new JLabel("Canny threshold: "));
JSlider slider = new JSlider(0, MAX_THRESHOLD, threshold);
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();
threshold = source.getValue();
update();
}
});
sliderPanel.add(slider);
pane.add(sliderPanel, BorderLayout.PAGE_START);
JPanel imgPanel = new JPanel();
imgSrcLabel = new JLabel(new ImageIcon(img));
imgPanel.add(imgSrcLabel);
Mat blackImg = Mat.zeros(srcGray.size(), CvType.CV_8U);
imgContoursLabel = new JLabel(new ImageIcon(HighGui.toBufferedImage(blackImg)));
imgPanel.add(imgContoursLabel);
pane.add(imgPanel, BorderLayout.CENTER);
}
private void update() {
/// Detect edges using Canny
Mat cannyOutput = new Mat();
Imgproc.Canny(srcGray, cannyOutput, threshold, threshold * 2);
/// Find contours
List<MatOfPoint> contours = new ArrayList<>();
Mat hierarchy = new Mat();
Imgproc.findContours(cannyOutput, contours, hierarchy, Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE);
/// Draw contours
Mat drawing = Mat.zeros(cannyOutput.size(), CvType.CV_8UC3);
for (int i = 0; i < contours.size(); i++) {
Scalar color = new Scalar(rng.nextInt(256), rng.nextInt(256), rng.nextInt(256));
Imgproc.drawContours(drawing, contours, i, color, 2, Core.LINE_8, hierarchy, 0, new Point());
}
imgContoursLabel.setIcon(new ImageIcon(HighGui.toBufferedImage(drawing)));
frame.repaint();
}
}
public class FindContoursDemo {
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 FindContours(args);
}
});
}
}
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Image;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
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.MatOfInt;
import org.opencv.core.MatOfPoint;
import org.opencv.core.Point;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
class Hull {
private Mat srcGray = new Mat();
private JFrame frame;
private JLabel imgSrcLabel;
private JLabel imgContoursLabel;
private static final int MAX_THRESHOLD = 255;
private int threshold = 100;
private Random rng = new Random(12345);
public Hull(String[] args) {
/// Load source image
String filename = args.length > 0 ? args[0] : "../data/stuff.jpg";
Mat src = Imgcodecs.imread(filename);
if (src.empty()) {
System.err.println("Cannot read image: " + filename);
System.exit(0);
}
/// Convert image to gray and blur it
Imgproc.cvtColor(src, srcGray, Imgproc.COLOR_BGR2GRAY);
Imgproc.blur(srcGray, srcGray, new Size(3, 3));
// Create and set up the window.
frame = new JFrame("Convex Hull 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);
update();
}
private void addComponentsToPane(Container pane, Image img) {
if (!(pane.getLayout() instanceof BorderLayout)) {
pane.add(new JLabel("Container doesn't use BorderLayout!"));
return;
}
JPanel sliderPanel = new JPanel();
sliderPanel.setLayout(new BoxLayout(sliderPanel, BoxLayout.PAGE_AXIS));
sliderPanel.add(new JLabel("Canny threshold: "));
JSlider slider = new JSlider(0, MAX_THRESHOLD, threshold);
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();
threshold = source.getValue();
update();
}
});
sliderPanel.add(slider);
pane.add(sliderPanel, BorderLayout.PAGE_START);
JPanel imgPanel = new JPanel();
imgSrcLabel = new JLabel(new ImageIcon(img));
imgPanel.add(imgSrcLabel);
Mat blackImg = Mat.zeros(srcGray.size(), CvType.CV_8U);
imgContoursLabel = new JLabel(new ImageIcon(HighGui.toBufferedImage(blackImg)));
imgPanel.add(imgContoursLabel);
pane.add(imgPanel, BorderLayout.CENTER);
}
private void update() {
/// Detect edges using Canny
Mat cannyOutput = new Mat();
Imgproc.Canny(srcGray, cannyOutput, threshold, threshold * 2);
/// Find contours
List<MatOfPoint> contours = new ArrayList<>();
Mat hierarchy = new Mat();
Imgproc.findContours(cannyOutput, contours, hierarchy, Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE);
/// Find the convex hull object for each contour
List<MatOfPoint> hullList = new ArrayList<>();
for (MatOfPoint contour : contours) {
MatOfInt hull = new MatOfInt();
Imgproc.convexHull(contour, hull);
Point[] contourArray = contour.toArray();
Point[] hullPoints = new Point[hull.rows()];
List<Integer> hullContourIdxList = hull.toList();
for (int i = 0; i < hullContourIdxList.size(); i++) {
hullPoints[i] = contourArray[hullContourIdxList.get(i)];
}
hullList.add(new MatOfPoint(hullPoints));
}
/// Draw contours + hull results
Mat drawing = Mat.zeros(cannyOutput.size(), CvType.CV_8UC3);
for (int i = 0; i < contours.size(); i++) {
Scalar color = new Scalar(rng.nextInt(256), rng.nextInt(256), rng.nextInt(256));
Imgproc.drawContours(drawing, contours, i, color);
Imgproc.drawContours(drawing, hullList, i, color );
}
imgContoursLabel.setIcon(new ImageIcon(HighGui.toBufferedImage(drawing)));
frame.repaint();
}
}
public class HullDemo {
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 Hull(args);
}
});
}
}
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Image;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
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.MatOfPoint;
import org.opencv.core.MatOfPoint2f;
import org.opencv.core.Point;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.imgproc.Moments;
class MomentsClass {
private Mat srcGray = new Mat();
private JFrame frame;
private JLabel imgSrcLabel;
private JLabel imgContoursLabel;
private static final int MAX_THRESHOLD = 255;
private int threshold = 100;
private Random rng = new Random(12345);
public MomentsClass(String[] args) {
//! [setup]
/// Load source image
String filename = args.length > 0 ? args[0] : "../data/stuff.jpg";
Mat src = Imgcodecs.imread(filename);
if (src.empty()) {
System.err.println("Cannot read image: " + filename);
System.exit(0);
}
/// Convert image to gray and blur it
Imgproc.cvtColor(src, srcGray, Imgproc.COLOR_BGR2GRAY);
Imgproc.blur(srcGray, srcGray, new Size(3, 3));
//! [setup]
//! [createWindow]
// Create and set up the window.
frame = new JFrame("Image Moments demo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Set up the content pane.
Image img = HighGui.toBufferedImage(src);
addComponentsToPane(frame.getContentPane(), img);
//! [createWindow]
// Use the content pane's default BorderLayout. No need for
// setLayout(new BorderLayout());
// Display the window.
frame.pack();
frame.setVisible(true);
update();
}
private void addComponentsToPane(Container pane, Image img) {
if (!(pane.getLayout() instanceof BorderLayout)) {
pane.add(new JLabel("Container doesn't use BorderLayout!"));
return;
}
JPanel sliderPanel = new JPanel();
sliderPanel.setLayout(new BoxLayout(sliderPanel, BoxLayout.PAGE_AXIS));
//! [trackbar]
sliderPanel.add(new JLabel("Canny threshold: "));
JSlider slider = new JSlider(0, MAX_THRESHOLD, threshold);
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();
threshold = source.getValue();
update();
}
});
//! [trackbar]
sliderPanel.add(slider);
pane.add(sliderPanel, BorderLayout.PAGE_START);
JPanel imgPanel = new JPanel();
imgSrcLabel = new JLabel(new ImageIcon(img));
imgPanel.add(imgSrcLabel);
Mat blackImg = Mat.zeros(srcGray.size(), CvType.CV_8U);
imgContoursLabel = new JLabel(new ImageIcon(HighGui.toBufferedImage(blackImg)));
imgPanel.add(imgContoursLabel);
pane.add(imgPanel, BorderLayout.CENTER);
}
private void update() {
//! [Canny]
/// Detect edges using Canny
Mat cannyOutput = new Mat();
Imgproc.Canny(srcGray, cannyOutput, threshold, threshold * 2);
//! [Canny]
//! [findContours]
/// Find contours
List<MatOfPoint> contours = new ArrayList<>();
Mat hierarchy = new Mat();
Imgproc.findContours(cannyOutput, contours, hierarchy, Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE);
//! [findContours]
/// Get the moments
List<Moments> mu = new ArrayList<>(contours.size());
for (int i = 0; i < contours.size(); i++) {
mu.add(Imgproc.moments(contours.get(i)));
}
/// Get the mass centers
List<Point> mc = new ArrayList<>(contours.size());
for (int i = 0; i < contours.size(); i++) {
//add 1e-5 to avoid division by zero
mc.add(new Point(mu.get(i).m10 / (mu.get(i).m00 + 1e-5), mu.get(i).m01 / (mu.get(i).m00 + 1e-5)));
}
//! [zeroMat]
/// Draw contours
Mat drawing = Mat.zeros(cannyOutput.size(), CvType.CV_8UC3);
//! [zeroMat]
//! [forContour]
for (int i = 0; i < contours.size(); i++) {
Scalar color = new Scalar(rng.nextInt(256), rng.nextInt(256), rng.nextInt(256));
Imgproc.drawContours(drawing, contours, i, color, 2);
Imgproc.circle(drawing, mc.get(i), 4, color, -1);
}
//! [forContour]
//! [showDrawings]
/// Show in a window
imgContoursLabel.setIcon(new ImageIcon(HighGui.toBufferedImage(drawing)));
frame.repaint();
//! [showDrawings]
/// Calculate the area with the moments 00 and compare with the result of the OpenCV function
System.out.println("\t Info: Area and Contour Length \n");
for (int i = 0; i < contours.size(); i++) {
System.out.format(" * Contour[%d] - Area (M_00) = %.2f - Area OpenCV: %.2f - Length: %.2f\n", i,
mu.get(i).m00, Imgproc.contourArea(contours.get(i)),
Imgproc.arcLength(new MatOfPoint2f(contours.get(i).toArray()), true));
}
}
}
public class MomentsDemo {
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 MomentsClass(args);
}
});
}
}
import java.util.ArrayList;
import java.util.List;
import org.opencv.core.Core;
import org.opencv.core.Core.MinMaxLocResult;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfPoint;
import org.opencv.core.MatOfPoint2f;
import org.opencv.core.Point;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.highgui.HighGui;
import org.opencv.imgproc.Imgproc;
class PointPolygonTest {
public void run() {
/// Create an image
int r = 100;
Mat src = Mat.zeros(new Size(4 * r, 4 * r), CvType.CV_8U);
/// Create a sequence of points to make a contour
List<Point> vert = new ArrayList<>(6);
vert.add(new Point(3 * r / 2, 1.34 * r));
vert.add(new Point(1 * r, 2 * r));
vert.add(new Point(3 * r / 2, 2.866 * r));
vert.add(new Point(5 * r / 2, 2.866 * r));
vert.add(new Point(3 * r, 2 * r));
vert.add(new Point(5 * r / 2, 1.34 * r));
/// Draw it in src
for (int i = 0; i < 6; i++) {
Imgproc.line(src, vert.get(i), vert.get((i + 1) % 6), new Scalar(255), 3);
}
/// Get the contours
List<MatOfPoint> contours = new ArrayList<>();
Mat hierarchy = new Mat();
Imgproc.findContours(src, contours, hierarchy, Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE);
/// Calculate the distances to the contour
Mat rawDist = new Mat(src.size(), CvType.CV_32F);
float[] rawDistData = new float[(int) (rawDist.total() * rawDist.channels())];
for (int i = 0; i < src.rows(); i++) {
for (int j = 0; j < src.cols(); j++) {
rawDistData[i * src.cols() + j] = (float) Imgproc
.pointPolygonTest(new MatOfPoint2f(contours.get(0).toArray()), new Point(j, i), true);
}
}
rawDist.put(0, 0, rawDistData);
MinMaxLocResult res = Core.minMaxLoc(rawDist);
double minVal = Math.abs(res.minVal);
double maxVal = Math.abs(res.maxVal);
/// Depicting the distances graphically
Mat drawing = Mat.zeros(src.size(), CvType.CV_8UC3);
byte[] drawingData = new byte[(int) (drawing.total() * drawing.channels())];
for (int i = 0; i < src.rows(); i++) {
for (int j = 0; j < src.cols(); j++) {
if (rawDistData[i * src.cols() + j] < 0) {
drawingData[(i * src.cols() + j) * 3] =
(byte) (255 - Math.abs(rawDistData[i * src.cols() + j]) * 255 / minVal);
} else if (rawDistData[i * src.cols() + j] > 0) {
drawingData[(i * src.cols() + j) * 3 + 2] =
(byte) (255 - rawDistData[i * src.cols() + j] * 255 / maxVal);
} else {
drawingData[(i * src.cols() + j) * 3] = (byte) 255;
drawingData[(i * src.cols() + j) * 3 + 1] = (byte) 255;
drawingData[(i * src.cols() + j) * 3 + 2] = (byte) 255;
}
}
}
drawing.put(0, 0, drawingData);
/// Show your results
HighGui.imshow("Source", src);
HighGui.imshow("Distance", drawing);
HighGui.waitKey();
System.exit(0);
}
}
public class PointPolygonTestDemo {
public static void main(String[] args) {
// Load the native OpenCV library
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
new PointPolygonTest().run();
}
}
from __future__ import print_function
import cv2 as cv
import numpy as np
import argparse
import random as rng
rng.seed(12345)
def thresh_callback(val):
threshold = val
## [Canny]
# Detect edges using Canny
canny_output = cv.Canny(src_gray, threshold, threshold * 2)
## [Canny]
## [findContours]
# Find contours
_, contours, _ = cv.findContours(canny_output, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
## [findContours]
## [allthework]
# Approximate contours to polygons + get bounding rects and circles
contours_poly = [None]*len(contours)
boundRect = [None]*len(contours)
centers = [None]*len(contours)
radius = [None]*len(contours)
for i in range(len(contours)):
contours_poly[i] = cv.approxPolyDP(contours[i], 3, True)
boundRect[i] = cv.boundingRect(contours_poly[i])
centers[i], radius[i] = cv.minEnclosingCircle(contours_poly[i])
## [allthework]
## [zeroMat]
drawing = np.zeros((canny_output.shape[0], canny_output.shape[1], 3), dtype=np.uint8)
## [zeroMat]
## [forContour]
# Draw polygonal contour + bonding rects + circles
for i in range(len(contours)):
color = (rng.randint(0,256), rng.randint(0,256), rng.randint(0,256))
cv.drawContours(drawing, contours_poly, i, color)
cv.rectangle(drawing, (int(boundRect[i][0]), int(boundRect[i][1])), \
(int(boundRect[i][0]+boundRect[i][2]), int(boundRect[i][1]+boundRect[i][3])), color, 2)
cv.circle(drawing, (int(centers[i][0]), int(centers[i][1])), int(radius[i]), color, 2)
## [forContour]
## [showDrawings]
# Show in a window
cv.imshow('Contours', drawing)
## [showDrawings]
## [setup]
# Load source image
parser = argparse.ArgumentParser(description='Code for Creating Bounding boxes and circles for contours tutorial.')
parser.add_argument('--input', help='Path to input image.', default='../data/stuff.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)
# Convert image to gray and blur it
src_gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
src_gray = cv.blur(src_gray, (3,3))
## [setup]
## [createWindow]
# Create Window
source_window = 'Source'
cv.namedWindow(source_window)
cv.imshow(source_window, src)
## [createWindow]
## [trackbar]
max_thresh = 255
thresh = 100 # initial threshold
cv.createTrackbar('Canny thresh:', source_window, thresh, max_thresh, thresh_callback)
thresh_callback(thresh)
## [trackbar]
cv.waitKey()
from __future__ import print_function
import cv2 as cv
import numpy as np
import argparse
import random as rng
rng.seed(12345)
def thresh_callback(val):
threshold = val
## [Canny]
# Detect edges using Canny
canny_output = cv.Canny(src_gray, threshold, threshold * 2)
## [Canny]
## [findContours]
# Find contours
_, contours, _ = cv.findContours(canny_output, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
## [findContours]
# Find the rotated rectangles and ellipses for each contour
minRect = [None]*len(contours)
minEllipse = [None]*len(contours)
for i in range(len(contours)):
minRect[i] = cv.minAreaRect(contours[i])
if contours[i].shape[0] > 5:
minEllipse[i] = cv.fitEllipse(contours[i])
# Draw contours + rotated rects + ellipses
## [zeroMat]
drawing = np.zeros((canny_output.shape[0], canny_output.shape[1], 3), dtype=np.uint8)
## [zeroMat]
## [forContour]
for i in range(len(contours)):
color = (rng.randint(0,256), rng.randint(0,256), rng.randint(0,256))
# contour
cv.drawContours(drawing, contours, i, color)
# ellipse
if contours[i].shape[0] > 5:
cv.ellipse(drawing, minEllipse[i], color, 2)
# rotated rectangle
box = cv.boxPoints(minRect[i])
box = np.intp(box) #np.intp: Integer used for indexing (same as C ssize_t; normally either int32 or int64)
cv.drawContours(drawing, [box], 0, color)
## [forContour]
## [showDrawings]
# Show in a window
cv.imshow('Contours', drawing)
## [showDrawings]
## [setup]
# Load source image
parser = argparse.ArgumentParser(description='Code for Creating Bounding rotated boxes and ellipses for contours tutorial.')
parser.add_argument('--input', help='Path to input image.', default='../data/stuff.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)
# Convert image to gray and blur it
src_gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
src_gray = cv.blur(src_gray, (3,3))
## [setup]
## [createWindow]
# Create Window
source_window = 'Source'
cv.namedWindow(source_window)
cv.imshow(source_window, src)
## [createWindow]
## [trackbar]
max_thresh = 255
thresh = 100 # initial threshold
cv.createTrackbar('Canny Thresh:', source_window, thresh, max_thresh, thresh_callback)
thresh_callback(thresh)
## [trackbar]
cv.waitKey()
from __future__ import print_function
import cv2 as cv
import numpy as np
import argparse
import random as rng
rng.seed(12345)
def thresh_callback(val):
threshold = val
# Detect edges using Canny
canny_output = cv.Canny(src_gray, threshold, threshold * 2)
# Find contours
_, contours, hierarchy = cv.findContours(canny_output, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
# Draw contours
drawing = np.zeros((canny_output.shape[0], canny_output.shape[1], 3), dtype=np.uint8)
for i in range(len(contours)):
color = (rng.randint(0,256), rng.randint(0,256), rng.randint(0,256))
cv.drawContours(drawing, contours, i, color, 2, cv.LINE_8, hierarchy, 0)
# Show in a window
cv.imshow('Contours', drawing)
# Load source image
parser = argparse.ArgumentParser(description='Code for Finding contours in your image tutorial.')
parser.add_argument('--input', help='Path to input image.', default='../data/HappyFish.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)
# Convert image to gray and blur it
src_gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
src_gray = cv.blur(src_gray, (3,3))
# Create Window
source_window = 'Source'
cv.namedWindow(source_window)
cv.imshow(source_window, src)
max_thresh = 255
thresh = 100 # initial threshold
cv.createTrackbar('Canny Thresh:', source_window, thresh, max_thresh, thresh_callback)
thresh_callback(thresh)
cv.waitKey()
from __future__ import print_function
import cv2 as cv
import numpy as np
import argparse
import random as rng
rng.seed(12345)
def thresh_callback(val):
threshold = val
# Detect edges using Canny
canny_output = cv.Canny(src_gray, threshold, threshold * 2)
# Find contours
_, contours, _ = cv.findContours(canny_output, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
# Find the convex hull object for each contour
hull_list = []
for i in range(len(contours)):
hull = cv.convexHull(contours[i])
hull_list.append(hull)
# Draw contours + hull results
drawing = np.zeros((canny_output.shape[0], canny_output.shape[1], 3), dtype=np.uint8)
for i in range(len(contours)):
color = (rng.randint(0,256), rng.randint(0,256), rng.randint(0,256))
cv.drawContours(drawing, contours, i, color)
cv.drawContours(drawing, hull_list, i, color)
# Show in a window
cv.imshow('Contours', drawing)
# Load source image
parser = argparse.ArgumentParser(description='Code for Convex Hull tutorial.')
parser.add_argument('--input', help='Path to input image.', default='../data/stuff.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)
# Convert image to gray and blur it
src_gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
src_gray = cv.blur(src_gray, (3,3))
# Create Window
source_window = 'Source'
cv.namedWindow(source_window)
cv.imshow(source_window, src)
max_thresh = 255
thresh = 100 # initial threshold
cv.createTrackbar('Canny thresh:', source_window, thresh, max_thresh, thresh_callback)
thresh_callback(thresh)
cv.waitKey()
from __future__ import print_function
from __future__ import division
import cv2 as cv
import numpy as np
import argparse
import random as rng
rng.seed(12345)
def thresh_callback(val):
threshold = val
## [Canny]
# Detect edges using Canny
canny_output = cv.Canny(src_gray, threshold, threshold * 2)
## [Canny]
## [findContours]
# Find contours
_, contours, _ = cv.findContours(canny_output, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
## [findContours]
# Get the moments
mu = [None]*len(contours)
for i in range(len(contours)):
mu[i] = cv.moments(contours[i])
# Get the mass centers
mc = [None]*len(contours)
for i in range(len(contours)):
# add 1e-5 to avoid division by zero
mc[i] = (mu[i]['m10'] / (mu[i]['m00'] + 1e-5), mu[i]['m01'] / (mu[i]['m00'] + 1e-5))
# Draw contours
## [zeroMat]
drawing = np.zeros((canny_output.shape[0], canny_output.shape[1], 3), dtype=np.uint8)
## [zeroMat]
## [forContour]
for i in range(len(contours)):
color = (rng.randint(0,256), rng.randint(0,256), rng.randint(0,256))
cv.drawContours(drawing, contours, i, color, 2)
cv.circle(drawing, (int(mc[i][0]), int(mc[i][1])), 4, color, -1)
## [forContour]
## [showDrawings]
# Show in a window
cv.imshow('Contours', drawing)
## [showDrawings]
# Calculate the area with the moments 00 and compare with the result of the OpenCV function
for i in range(len(contours)):
print(' * Contour[%d] - Area (M_00) = %.2f - Area OpenCV: %.2f - Length: %.2f' % (i, mu[i]['m00'], cv.contourArea(contours[i]), cv.arcLength(contours[i], True)))
## [setup]
# Load source image
parser = argparse.ArgumentParser(description='Code for Image Moments tutorial.')
parser.add_argument('--input', help='Path to input image.', default='../data/stuff.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)
# Convert image to gray and blur it
src_gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
src_gray = cv.blur(src_gray, (3,3))
## [setup]
## [createWindow]
# Create Window
source_window = 'Source'
cv.namedWindow(source_window)
cv.imshow(source_window, src)
## [createWindow]
## [trackbar]
max_thresh = 255
thresh = 100 # initial threshold
cv.createTrackbar('Canny Thresh:', source_window, thresh, max_thresh, thresh_callback)
thresh_callback(thresh)
## [trackbar]
cv.waitKey()
from __future__ import print_function
from __future__ import division
import cv2 as cv
import numpy as np
# Create an image
r = 100
src = np.zeros((4*r, 4*r), dtype=np.uint8)
# Create a sequence of points to make a contour
vert = [None]*6
vert[0] = (3*r//2, int(1.34*r))
vert[1] = (1*r, 2*r)
vert[2] = (3*r//2, int(2.866*r))
vert[3] = (5*r//2, int(2.866*r))
vert[4] = (3*r, 2*r)
vert[5] = (5*r//2, int(1.34*r))
# Draw it in src
for i in range(6):
cv.line(src, vert[i], vert[(i+1)%6], ( 255 ), 3)
# Get the contours
_, contours, _ = cv.findContours(src, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
# Calculate the distances to the contour
raw_dist = np.empty(src.shape, dtype=np.float32)
for i in range(src.shape[0]):
for j in range(src.shape[1]):
raw_dist[i,j] = cv.pointPolygonTest(contours[0], (j,i), True)
minVal, maxVal, _, _ = cv.minMaxLoc(raw_dist)
minVal = abs(minVal)
maxVal = abs(maxVal)
# Depicting the distances graphically
drawing = np.zeros((src.shape[0], src.shape[1], 3), dtype=np.uint8)
for i in range(src.shape[0]):
for j in range(src.shape[1]):
if raw_dist[i,j] < 0:
drawing[i,j,0] = 255 - abs(raw_dist[i,j]) * 255 / minVal
elif raw_dist[i,j] > 0:
drawing[i,j,2] = 255 - raw_dist[i,j] * 255 / maxVal
else:
drawing[i,j,0] = 255
drawing[i,j,1] = 255
drawing[i,j,2] = 255
cv.imshow('Source', src)
cv.imshow('Distance', drawing)
cv.waitKey()
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