mirror of
https://github.com/opencv/opencv.git
synced 2026-07-30 07:43:03 +04:00
Merge remote-tracking branch 'upstream/3.4' into merge-3.4
Revert "documentation: avoid links to 'master' branch from 3.4 maintenance branch" This reverts commit9ba9358ecb. Revert "documentation: avoid links to 'master' branch from 3.4 maintenance branch (2)" This reverts commitf185802489.
This commit is contained in:
@@ -13,15 +13,15 @@ using namespace std;
|
||||
|
||||
/// Global variables
|
||||
Mat src, src_gray;
|
||||
Mat myHarris_dst; Mat myHarris_copy; Mat Mc;
|
||||
Mat myShiTomasi_dst; Mat myShiTomasi_copy;
|
||||
Mat myHarris_dst, myHarris_copy, Mc;
|
||||
Mat myShiTomasi_dst, myShiTomasi_copy;
|
||||
|
||||
int myShiTomasi_qualityLevel = 50;
|
||||
int myHarris_qualityLevel = 50;
|
||||
int max_qualityLevel = 100;
|
||||
|
||||
double myHarris_minVal; double myHarris_maxVal;
|
||||
double myShiTomasi_minVal; double myShiTomasi_maxVal;
|
||||
double myHarris_minVal, myHarris_maxVal;
|
||||
double myShiTomasi_minVal, myShiTomasi_maxVal;
|
||||
|
||||
RNG rng(12345);
|
||||
|
||||
@@ -37,56 +37,54 @@ void myHarris_function( int, void* );
|
||||
*/
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
/// Load source image and convert it to gray
|
||||
CommandLineParser parser( argc, argv, "{@input | ../data/stuff.jpg | input image}" );
|
||||
src = imread( parser.get<String>( "@input" ), IMREAD_COLOR );
|
||||
if ( src.empty() )
|
||||
{
|
||||
cout << "Could not open or find the image!\n" << endl;
|
||||
cout << "Usage: " << argv[0] << " <Input image>" << endl;
|
||||
return -1;
|
||||
}
|
||||
cvtColor( src, src_gray, COLOR_BGR2GRAY );
|
||||
/// Load source image and convert it to gray
|
||||
CommandLineParser parser( argc, argv, "{@input | ../data/building.jpg | input image}" );
|
||||
src = imread( parser.get<String>( "@input" ) );
|
||||
if ( src.empty() )
|
||||
{
|
||||
cout << "Could not open or find the image!\n" << endl;
|
||||
cout << "Usage: " << argv[0] << " <Input image>" << endl;
|
||||
return -1;
|
||||
}
|
||||
cvtColor( src, src_gray, COLOR_BGR2GRAY );
|
||||
|
||||
/// Set some parameters
|
||||
int blockSize = 3; int apertureSize = 3;
|
||||
/// Set some parameters
|
||||
int blockSize = 3, apertureSize = 3;
|
||||
|
||||
/// My Harris matrix -- Using cornerEigenValsAndVecs
|
||||
myHarris_dst = Mat::zeros( src_gray.size(), CV_32FC(6) );
|
||||
Mc = Mat::zeros( src_gray.size(), CV_32FC1 );
|
||||
/// My Harris matrix -- Using cornerEigenValsAndVecs
|
||||
cornerEigenValsAndVecs( src_gray, myHarris_dst, blockSize, apertureSize );
|
||||
|
||||
cornerEigenValsAndVecs( src_gray, myHarris_dst, blockSize, apertureSize, BORDER_DEFAULT );
|
||||
/* calculate Mc */
|
||||
Mc = Mat( src_gray.size(), CV_32FC1 );
|
||||
for( int i = 0; i < src_gray.rows; i++ )
|
||||
{
|
||||
for( int j = 0; j < src_gray.cols; j++ )
|
||||
{
|
||||
float lambda_1 = myHarris_dst.at<Vec6f>(i, j)[0];
|
||||
float lambda_2 = myHarris_dst.at<Vec6f>(i, j)[1];
|
||||
Mc.at<float>(i, j) = lambda_1*lambda_2 - 0.04f*pow( ( lambda_1 + lambda_2 ), 2 );
|
||||
}
|
||||
}
|
||||
|
||||
/* calculate Mc */
|
||||
for( int j = 0; j < src_gray.rows; j++ )
|
||||
{ for( int i = 0; i < src_gray.cols; i++ )
|
||||
{
|
||||
float lambda_1 = myHarris_dst.at<Vec6f>(j, i)[0];
|
||||
float lambda_2 = myHarris_dst.at<Vec6f>(j, i)[1];
|
||||
Mc.at<float>(j,i) = lambda_1*lambda_2 - 0.04f*pow( ( lambda_1 + lambda_2 ), 2 );
|
||||
}
|
||||
}
|
||||
minMaxLoc( Mc, &myHarris_minVal, &myHarris_maxVal );
|
||||
|
||||
minMaxLoc( Mc, &myHarris_minVal, &myHarris_maxVal, 0, 0, Mat() );
|
||||
/* Create Window and Trackbar */
|
||||
namedWindow( myHarris_window );
|
||||
createTrackbar( "Quality Level:", myHarris_window, &myHarris_qualityLevel, max_qualityLevel, myHarris_function );
|
||||
myHarris_function( 0, 0 );
|
||||
|
||||
/* Create Window and Trackbar */
|
||||
namedWindow( myHarris_window, WINDOW_AUTOSIZE );
|
||||
createTrackbar( " Quality Level:", myHarris_window, &myHarris_qualityLevel, max_qualityLevel, myHarris_function );
|
||||
myHarris_function( 0, 0 );
|
||||
/// My Shi-Tomasi -- Using cornerMinEigenVal
|
||||
cornerMinEigenVal( src_gray, myShiTomasi_dst, blockSize, apertureSize );
|
||||
|
||||
/// My Shi-Tomasi -- Using cornerMinEigenVal
|
||||
myShiTomasi_dst = Mat::zeros( src_gray.size(), CV_32FC1 );
|
||||
cornerMinEigenVal( src_gray, myShiTomasi_dst, blockSize, apertureSize, BORDER_DEFAULT );
|
||||
minMaxLoc( myShiTomasi_dst, &myShiTomasi_minVal, &myShiTomasi_maxVal );
|
||||
|
||||
minMaxLoc( myShiTomasi_dst, &myShiTomasi_minVal, &myShiTomasi_maxVal, 0, 0, Mat() );
|
||||
/* Create Window and Trackbar */
|
||||
namedWindow( myShiTomasi_window );
|
||||
createTrackbar( "Quality Level:", myShiTomasi_window, &myShiTomasi_qualityLevel, max_qualityLevel, myShiTomasi_function );
|
||||
myShiTomasi_function( 0, 0 );
|
||||
|
||||
/* Create Window and Trackbar */
|
||||
namedWindow( myShiTomasi_window, WINDOW_AUTOSIZE );
|
||||
createTrackbar( " Quality Level:", myShiTomasi_window, &myShiTomasi_qualityLevel, max_qualityLevel, myShiTomasi_function );
|
||||
myShiTomasi_function( 0, 0 );
|
||||
|
||||
waitKey(0);
|
||||
return(0);
|
||||
waitKey();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -94,18 +92,20 @@ int main( int argc, char** argv )
|
||||
*/
|
||||
void myShiTomasi_function( int, void* )
|
||||
{
|
||||
myShiTomasi_copy = src.clone();
|
||||
myShiTomasi_copy = src.clone();
|
||||
myShiTomasi_qualityLevel = MAX(myShiTomasi_qualityLevel, 1);
|
||||
|
||||
if( myShiTomasi_qualityLevel < 1 ) { myShiTomasi_qualityLevel = 1; }
|
||||
|
||||
for( int j = 0; j < src_gray.rows; j++ )
|
||||
{ for( int i = 0; i < src_gray.cols; i++ )
|
||||
{
|
||||
if( myShiTomasi_dst.at<float>(j,i) > myShiTomasi_minVal + ( myShiTomasi_maxVal - myShiTomasi_minVal )*myShiTomasi_qualityLevel/max_qualityLevel )
|
||||
{ circle( myShiTomasi_copy, Point(i,j), 4, Scalar( rng.uniform(0,255), rng.uniform(0,255), rng.uniform(0,255) ), -1, 8, 0 ); }
|
||||
}
|
||||
}
|
||||
imshow( myShiTomasi_window, myShiTomasi_copy );
|
||||
for( int i = 0; i < src_gray.rows; i++ )
|
||||
{
|
||||
for( int j = 0; j < src_gray.cols; j++ )
|
||||
{
|
||||
if( myShiTomasi_dst.at<float>(i,j) > myShiTomasi_minVal + ( myShiTomasi_maxVal - myShiTomasi_minVal )*myShiTomasi_qualityLevel/max_qualityLevel )
|
||||
{
|
||||
circle( myShiTomasi_copy, Point(j,i), 4, Scalar( rng.uniform(0,256), rng.uniform(0,256), rng.uniform(0,256) ), FILLED );
|
||||
}
|
||||
}
|
||||
}
|
||||
imshow( myShiTomasi_window, myShiTomasi_copy );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -113,16 +113,18 @@ void myShiTomasi_function( int, void* )
|
||||
*/
|
||||
void myHarris_function( int, void* )
|
||||
{
|
||||
myHarris_copy = src.clone();
|
||||
myHarris_copy = src.clone();
|
||||
myHarris_qualityLevel = MAX(myHarris_qualityLevel, 1);
|
||||
|
||||
if( myHarris_qualityLevel < 1 ) { myHarris_qualityLevel = 1; }
|
||||
|
||||
for( int j = 0; j < src_gray.rows; j++ )
|
||||
{ for( int i = 0; i < src_gray.cols; i++ )
|
||||
{
|
||||
if( Mc.at<float>(j,i) > myHarris_minVal + ( myHarris_maxVal - myHarris_minVal )*myHarris_qualityLevel/max_qualityLevel )
|
||||
{ circle( myHarris_copy, Point(i,j), 4, Scalar( rng.uniform(0,255), rng.uniform(0,255), rng.uniform(0,255) ), -1, 8, 0 ); }
|
||||
}
|
||||
}
|
||||
imshow( myHarris_window, myHarris_copy );
|
||||
for( int i = 0; i < src_gray.rows; i++ )
|
||||
{
|
||||
for( int j = 0; j < src_gray.cols; j++ )
|
||||
{
|
||||
if( Mc.at<float>(i,j) > myHarris_minVal + ( myHarris_maxVal - myHarris_minVal )*myHarris_qualityLevel/max_qualityLevel )
|
||||
{
|
||||
circle( myHarris_copy, Point(j,i), 4, Scalar( rng.uniform(0,256), rng.uniform(0,256), rng.uniform(0,256) ), FILLED );
|
||||
}
|
||||
}
|
||||
}
|
||||
imshow( myHarris_window, myHarris_copy );
|
||||
}
|
||||
|
||||
@@ -27,26 +27,26 @@ void cornerHarris_demo( int, void* );
|
||||
*/
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
/// Load source image and convert it to gray
|
||||
CommandLineParser parser( argc, argv, "{@input | ../data/building.jpg | input image}" );
|
||||
src = imread( parser.get<String>( "@input" ), IMREAD_COLOR );
|
||||
if ( src.empty() )
|
||||
{
|
||||
cout << "Could not open or find the image!\n" << endl;
|
||||
cout << "Usage: " << argv[0] << " <Input image>" << endl;
|
||||
return -1;
|
||||
}
|
||||
cvtColor( src, src_gray, COLOR_BGR2GRAY );
|
||||
/// Load source image and convert it to gray
|
||||
CommandLineParser parser( argc, argv, "{@input | ../data/building.jpg | input image}" );
|
||||
src = imread( parser.get<String>( "@input" ) );
|
||||
if ( src.empty() )
|
||||
{
|
||||
cout << "Could not open or find the image!\n" << endl;
|
||||
cout << "Usage: " << argv[0] << " <Input image>" << endl;
|
||||
return -1;
|
||||
}
|
||||
cvtColor( src, src_gray, COLOR_BGR2GRAY );
|
||||
|
||||
/// Create a window and a trackbar
|
||||
namedWindow( source_window, WINDOW_AUTOSIZE );
|
||||
createTrackbar( "Threshold: ", source_window, &thresh, max_thresh, cornerHarris_demo );
|
||||
imshow( source_window, src );
|
||||
/// Create a window and a trackbar
|
||||
namedWindow( source_window );
|
||||
createTrackbar( "Threshold: ", source_window, &thresh, max_thresh, cornerHarris_demo );
|
||||
imshow( source_window, src );
|
||||
|
||||
cornerHarris_demo( 0, 0 );
|
||||
cornerHarris_demo( 0, 0 );
|
||||
|
||||
waitKey(0);
|
||||
return(0);
|
||||
waitKey();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -55,33 +55,33 @@ int main( int argc, char** argv )
|
||||
*/
|
||||
void cornerHarris_demo( int, void* )
|
||||
{
|
||||
/// Detector parameters
|
||||
int blockSize = 2;
|
||||
int apertureSize = 3;
|
||||
double k = 0.04;
|
||||
|
||||
Mat dst, dst_norm, dst_norm_scaled;
|
||||
dst = Mat::zeros( src.size(), CV_32FC1 );
|
||||
/// Detecting corners
|
||||
Mat dst = Mat::zeros( src.size(), CV_32FC1 );
|
||||
cornerHarris( src_gray, dst, blockSize, apertureSize, k );
|
||||
|
||||
/// Detector parameters
|
||||
int blockSize = 2;
|
||||
int apertureSize = 3;
|
||||
double k = 0.04;
|
||||
/// Normalizing
|
||||
Mat dst_norm, dst_norm_scaled;
|
||||
normalize( dst, dst_norm, 0, 255, NORM_MINMAX, CV_32FC1, Mat() );
|
||||
convertScaleAbs( dst_norm, dst_norm_scaled );
|
||||
|
||||
/// Detecting corners
|
||||
cornerHarris( src_gray, dst, blockSize, apertureSize, k, BORDER_DEFAULT );
|
||||
/// Drawing a circle around corners
|
||||
for( int i = 0; i < dst_norm.rows ; i++ )
|
||||
{
|
||||
for( int j = 0; j < dst_norm.cols; j++ )
|
||||
{
|
||||
if( (int) dst_norm.at<float>(i,j) > thresh )
|
||||
{
|
||||
circle( dst_norm_scaled, Point(j,i), 5, Scalar(0), 2, 8, 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Normalizing
|
||||
normalize( dst, dst_norm, 0, 255, NORM_MINMAX, CV_32FC1, Mat() );
|
||||
convertScaleAbs( dst_norm, dst_norm_scaled );
|
||||
|
||||
/// Drawing a circle around corners
|
||||
for( int j = 0; j < dst_norm.rows ; j++ )
|
||||
{ for( int i = 0; i < dst_norm.cols; i++ )
|
||||
{
|
||||
if( (int) dst_norm.at<float>(j,i) > thresh )
|
||||
{
|
||||
circle( dst_norm_scaled, Point( i, j ), 5, Scalar(0), 2, 8, 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
/// Showing the result
|
||||
namedWindow( corners_window, WINDOW_AUTOSIZE );
|
||||
imshow( corners_window, dst_norm_scaled );
|
||||
/// Showing the result
|
||||
namedWindow( corners_window );
|
||||
imshow( corners_window, dst_norm_scaled );
|
||||
}
|
||||
|
||||
@@ -28,29 +28,29 @@ void goodFeaturesToTrack_Demo( int, void* );
|
||||
*/
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
/// Load source image and convert it to gray
|
||||
CommandLineParser parser( argc, argv, "{@input | ../data/pic3.png | input image}" );
|
||||
src = imread(parser.get<String>( "@input" ), IMREAD_COLOR);
|
||||
if ( src.empty() )
|
||||
{
|
||||
cout << "Could not open or find the image!\n" << endl;
|
||||
cout << "Usage: " << argv[0] << " <Input image>" << endl;
|
||||
return -1;
|
||||
}
|
||||
cvtColor( src, src_gray, COLOR_BGR2GRAY );
|
||||
/// Load source image and convert it to gray
|
||||
CommandLineParser parser( argc, argv, "{@input | ../data/pic3.png | input image}" );
|
||||
src = imread( parser.get<String>( "@input" ) );
|
||||
if( src.empty() )
|
||||
{
|
||||
cout << "Could not open or find the image!\n" << endl;
|
||||
cout << "Usage: " << argv[0] << " <Input image>" << endl;
|
||||
return -1;
|
||||
}
|
||||
cvtColor( src, src_gray, COLOR_BGR2GRAY );
|
||||
|
||||
/// Create Window
|
||||
namedWindow( source_window, WINDOW_AUTOSIZE );
|
||||
/// Create Window
|
||||
namedWindow( source_window );
|
||||
|
||||
/// Create Trackbar to set the number of corners
|
||||
createTrackbar( "Max corners:", source_window, &maxCorners, maxTrackbar, goodFeaturesToTrack_Demo );
|
||||
/// Create Trackbar to set the number of corners
|
||||
createTrackbar( "Max corners:", source_window, &maxCorners, maxTrackbar, goodFeaturesToTrack_Demo );
|
||||
|
||||
imshow( source_window, src );
|
||||
imshow( source_window, src );
|
||||
|
||||
goodFeaturesToTrack_Demo( 0, 0 );
|
||||
goodFeaturesToTrack_Demo( 0, 0 );
|
||||
|
||||
waitKey(0);
|
||||
return(0);
|
||||
waitKey();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -59,52 +59,54 @@ int main( int argc, char** argv )
|
||||
*/
|
||||
void goodFeaturesToTrack_Demo( int, void* )
|
||||
{
|
||||
if( maxCorners < 1 ) { maxCorners = 1; }
|
||||
/// Parameters for Shi-Tomasi algorithm
|
||||
maxCorners = MAX(maxCorners, 1);
|
||||
vector<Point2f> corners;
|
||||
double qualityLevel = 0.01;
|
||||
double minDistance = 10;
|
||||
int blockSize = 3, gradientSize = 3;
|
||||
bool useHarrisDetector = false;
|
||||
double k = 0.04;
|
||||
|
||||
/// Parameters for Shi-Tomasi algorithm
|
||||
vector<Point2f> corners;
|
||||
double qualityLevel = 0.01;
|
||||
double minDistance = 10;
|
||||
int blockSize = 3, gradiantSize = 3;
|
||||
bool useHarrisDetector = false;
|
||||
double k = 0.04;
|
||||
/// Copy the source image
|
||||
Mat copy = src.clone();
|
||||
|
||||
/// Copy the source image
|
||||
Mat copy;
|
||||
copy = src.clone();
|
||||
|
||||
/// Apply corner detection
|
||||
goodFeaturesToTrack( src_gray,
|
||||
corners,
|
||||
maxCorners,
|
||||
qualityLevel,
|
||||
minDistance,
|
||||
Mat(),
|
||||
blockSize,
|
||||
gradiantSize,
|
||||
useHarrisDetector,
|
||||
k );
|
||||
/// Apply corner detection
|
||||
goodFeaturesToTrack( src_gray,
|
||||
corners,
|
||||
maxCorners,
|
||||
qualityLevel,
|
||||
minDistance,
|
||||
Mat(),
|
||||
blockSize,
|
||||
gradientSize,
|
||||
useHarrisDetector,
|
||||
k );
|
||||
|
||||
|
||||
/// Draw corners detected
|
||||
cout<<"** Number of corners detected: "<<corners.size()<<endl;
|
||||
int r = 4;
|
||||
for( size_t i = 0; i < corners.size(); i++ )
|
||||
{ circle( copy, corners[i], r, Scalar(rng.uniform(0,255), rng.uniform(0,255), rng.uniform(0,255)), -1, 8, 0 ); }
|
||||
/// Draw corners detected
|
||||
cout << "** Number of corners detected: " << corners.size() << endl;
|
||||
int radius = 4;
|
||||
for( size_t i = 0; i < corners.size(); i++ )
|
||||
{
|
||||
circle( copy, corners[i], radius, Scalar(rng.uniform(0,255), rng.uniform(0, 256), rng.uniform(0, 256)), FILLED );
|
||||
}
|
||||
|
||||
/// Show what you got
|
||||
namedWindow( source_window, WINDOW_AUTOSIZE );
|
||||
imshow( source_window, copy );
|
||||
/// Show what you got
|
||||
namedWindow( source_window );
|
||||
imshow( source_window, copy );
|
||||
|
||||
/// Set the needed parameters to find the refined corners
|
||||
Size winSize = Size( 5, 5 );
|
||||
Size zeroZone = Size( -1, -1 );
|
||||
TermCriteria criteria = TermCriteria( TermCriteria::EPS + TermCriteria::COUNT, 40, 0.001 );
|
||||
/// Set the needed parameters to find the refined corners
|
||||
Size winSize = Size( 5, 5 );
|
||||
Size zeroZone = Size( -1, -1 );
|
||||
TermCriteria criteria = TermCriteria( TermCriteria::EPS + TermCriteria::COUNT, 40, 0.001 );
|
||||
|
||||
/// Calculate the refined corner locations
|
||||
cornerSubPix( src_gray, corners, winSize, zeroZone, criteria );
|
||||
/// Calculate the refined corner locations
|
||||
cornerSubPix( src_gray, corners, winSize, zeroZone, criteria );
|
||||
|
||||
/// Write them down
|
||||
for( size_t i = 0; i < corners.size(); i++ )
|
||||
{ cout<<" -- Refined Corner ["<<i<<"] ("<<corners[i].x<<","<<corners[i].y<<")"<<endl; }
|
||||
/// Write them down
|
||||
for( size_t i = 0; i < corners.size(); i++ )
|
||||
{
|
||||
cout << " -- Refined Corner [" << i << "] (" << corners[i].x << "," << corners[i].y << ")" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,29 +29,29 @@ void goodFeaturesToTrack_Demo( int, void* );
|
||||
*/
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
/// Load source image and convert it to gray
|
||||
CommandLineParser parser( argc, argv, "{@input | ../data/pic3.png | input image}" );
|
||||
src = imread( parser.get<String>( "@input" ), IMREAD_COLOR );
|
||||
if( src.empty() )
|
||||
{
|
||||
cout << "Could not open or find the image!\n" << endl;
|
||||
cout << "Usage: " << argv[0] << " <Input image>" << endl;
|
||||
return -1;
|
||||
}
|
||||
cvtColor( src, src_gray, COLOR_BGR2GRAY );
|
||||
/// Load source image and convert it to gray
|
||||
CommandLineParser parser( argc, argv, "{@input | ../data/pic3.png | input image}" );
|
||||
src = imread( parser.get<String>( "@input" ) );
|
||||
if( src.empty() )
|
||||
{
|
||||
cout << "Could not open or find the image!\n" << endl;
|
||||
cout << "Usage: " << argv[0] << " <Input image>" << endl;
|
||||
return -1;
|
||||
}
|
||||
cvtColor( src, src_gray, COLOR_BGR2GRAY );
|
||||
|
||||
/// Create Window
|
||||
namedWindow( source_window, WINDOW_AUTOSIZE );
|
||||
/// Create Window
|
||||
namedWindow( source_window );
|
||||
|
||||
/// Create Trackbar to set the number of corners
|
||||
createTrackbar( "Max corners:", source_window, &maxCorners, maxTrackbar, goodFeaturesToTrack_Demo );
|
||||
/// Create Trackbar to set the number of corners
|
||||
createTrackbar( "Max corners:", source_window, &maxCorners, maxTrackbar, goodFeaturesToTrack_Demo );
|
||||
|
||||
imshow( source_window, src );
|
||||
imshow( source_window, src );
|
||||
|
||||
goodFeaturesToTrack_Demo( 0, 0 );
|
||||
goodFeaturesToTrack_Demo( 0, 0 );
|
||||
|
||||
waitKey(0);
|
||||
return(0);
|
||||
waitKey();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -60,40 +60,40 @@ int main( int argc, char** argv )
|
||||
*/
|
||||
void goodFeaturesToTrack_Demo( int, void* )
|
||||
{
|
||||
if( maxCorners < 1 ) { maxCorners = 1; }
|
||||
/// Parameters for Shi-Tomasi algorithm
|
||||
maxCorners = MAX(maxCorners, 1);
|
||||
vector<Point2f> corners;
|
||||
double qualityLevel = 0.01;
|
||||
double minDistance = 10;
|
||||
int blockSize = 3, gradientSize = 3;
|
||||
bool useHarrisDetector = false;
|
||||
double k = 0.04;
|
||||
|
||||
/// Parameters for Shi-Tomasi algorithm
|
||||
vector<Point2f> corners;
|
||||
double qualityLevel = 0.01;
|
||||
double minDistance = 10;
|
||||
int blockSize = 3, gradiantSize = 3;
|
||||
bool useHarrisDetector = false;
|
||||
double k = 0.04;
|
||||
/// Copy the source image
|
||||
Mat copy = src.clone();
|
||||
|
||||
/// Copy the source image
|
||||
Mat copy;
|
||||
copy = src.clone();
|
||||
|
||||
/// Apply corner detection
|
||||
goodFeaturesToTrack( src_gray,
|
||||
corners,
|
||||
maxCorners,
|
||||
qualityLevel,
|
||||
minDistance,
|
||||
Mat(),
|
||||
blockSize,
|
||||
gradiantSize,
|
||||
useHarrisDetector,
|
||||
k );
|
||||
/// Apply corner detection
|
||||
goodFeaturesToTrack( src_gray,
|
||||
corners,
|
||||
maxCorners,
|
||||
qualityLevel,
|
||||
minDistance,
|
||||
Mat(),
|
||||
blockSize,
|
||||
gradientSize,
|
||||
useHarrisDetector,
|
||||
k );
|
||||
|
||||
|
||||
/// Draw corners detected
|
||||
cout<<"** Number of corners detected: "<<corners.size()<<endl;
|
||||
int r = 4;
|
||||
for( size_t i = 0; i < corners.size(); i++ )
|
||||
{ circle( copy, corners[i], r, Scalar(rng.uniform(0,255), rng.uniform(0,255), rng.uniform(0,255)), -1, 8, 0 ); }
|
||||
/// Draw corners detected
|
||||
cout << "** Number of corners detected: " << corners.size() << endl;
|
||||
int radius = 4;
|
||||
for( size_t i = 0; i < corners.size(); i++ )
|
||||
{
|
||||
circle( copy, corners[i], radius, Scalar(rng.uniform(0,255), rng.uniform(0, 256), rng.uniform(0, 256)), FILLED );
|
||||
}
|
||||
|
||||
/// Show what you got
|
||||
namedWindow( source_window, WINDOW_AUTOSIZE );
|
||||
imshow( source_window, copy );
|
||||
/// Show what you got
|
||||
namedWindow( source_window );
|
||||
imshow( source_window, copy );
|
||||
}
|
||||
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
#include <iostream>
|
||||
#include "opencv2/core.hpp"
|
||||
#ifdef HAVE_OPENCV_XFEATURES2D
|
||||
#include "opencv2/highgui.hpp"
|
||||
#include "opencv2/features2d.hpp"
|
||||
#include "opencv2/xfeatures2d.hpp"
|
||||
|
||||
using namespace cv;
|
||||
using namespace cv::xfeatures2d;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
const char* keys =
|
||||
"{ help h | | Print help message. }"
|
||||
"{ input1 | ../data/box.png | Path to input image 1. }"
|
||||
"{ input2 | ../data/box_in_scene.png | Path to input image 2. }";
|
||||
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
CommandLineParser parser( argc, argv, keys );
|
||||
Mat img1 = imread( parser.get<String>("input1"), IMREAD_GRAYSCALE );
|
||||
Mat img2 = imread( parser.get<String>("input2"), IMREAD_GRAYSCALE );
|
||||
if ( img1.empty() || img2.empty() )
|
||||
{
|
||||
cout << "Could not open or find the image!\n" << endl;
|
||||
parser.printMessage();
|
||||
return -1;
|
||||
}
|
||||
|
||||
//-- Step 1: Detect the keypoints using SURF Detector, compute the descriptors
|
||||
int minHessian = 400;
|
||||
Ptr<SURF> detector = SURF::create( minHessian );
|
||||
std::vector<KeyPoint> keypoints1, keypoints2;
|
||||
Mat descriptors1, descriptors2;
|
||||
detector->detectAndCompute( img1, noArray(), keypoints1, descriptors1 );
|
||||
detector->detectAndCompute( img2, noArray(), keypoints2, descriptors2 );
|
||||
|
||||
//-- Step 2: Matching descriptor vectors with a brute force matcher
|
||||
// Since SURF is a floating-point descriptor NORM_L2 is used
|
||||
Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create(DescriptorMatcher::BRUTEFORCE);
|
||||
std::vector< DMatch > matches;
|
||||
matcher->match( descriptors1, descriptors2, matches );
|
||||
|
||||
//-- Draw matches
|
||||
Mat img_matches;
|
||||
drawMatches( img1, keypoints1, img2, keypoints2, matches, img_matches );
|
||||
|
||||
//-- Show detected matches
|
||||
imshow("Matches", img_matches );
|
||||
|
||||
waitKey();
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
int main()
|
||||
{
|
||||
std::cout << "This tutorial code needs the xfeatures2d contrib module to be run." << std::endl;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
#include <iostream>
|
||||
#include "opencv2/core.hpp"
|
||||
#ifdef HAVE_OPENCV_XFEATURES2D
|
||||
#include "opencv2/highgui.hpp"
|
||||
#include "opencv2/features2d.hpp"
|
||||
#include "opencv2/xfeatures2d.hpp"
|
||||
|
||||
using namespace cv;
|
||||
using namespace cv::xfeatures2d;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
CommandLineParser parser( argc, argv, "{@input | ../data/box.png | input image}" );
|
||||
Mat src = imread( parser.get<String>( "@input" ), IMREAD_GRAYSCALE );
|
||||
if ( src.empty() )
|
||||
{
|
||||
cout << "Could not open or find the image!\n" << endl;
|
||||
cout << "Usage: " << argv[0] << " <Input image>" << endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
//-- Step 1: Detect the keypoints using SURF Detector
|
||||
int minHessian = 400;
|
||||
Ptr<SURF> detector = SURF::create( minHessian );
|
||||
std::vector<KeyPoint> keypoints;
|
||||
detector->detect( src, keypoints );
|
||||
|
||||
//-- Draw keypoints
|
||||
Mat img_keypoints;
|
||||
drawKeypoints( src, keypoints, img_keypoints );
|
||||
|
||||
//-- Show detected (drawn) keypoints
|
||||
imshow("SURF Keypoints", img_keypoints );
|
||||
|
||||
waitKey();
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
int main()
|
||||
{
|
||||
std::cout << "This tutorial code needs the xfeatures2d contrib module to be run." << std::endl;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
#include <iostream>
|
||||
#include "opencv2/core.hpp"
|
||||
#ifdef HAVE_OPENCV_XFEATURES2D
|
||||
#include "opencv2/highgui.hpp"
|
||||
#include "opencv2/features2d.hpp"
|
||||
#include "opencv2/xfeatures2d.hpp"
|
||||
|
||||
using namespace cv;
|
||||
using namespace cv::xfeatures2d;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
const char* keys =
|
||||
"{ help h | | Print help message. }"
|
||||
"{ input1 | ../data/box.png | Path to input image 1. }"
|
||||
"{ input2 | ../data/box_in_scene.png | Path to input image 2. }";
|
||||
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
CommandLineParser parser( argc, argv, keys );
|
||||
Mat img1 = imread( parser.get<String>("input1"), IMREAD_GRAYSCALE );
|
||||
Mat img2 = imread( parser.get<String>("input2"), IMREAD_GRAYSCALE );
|
||||
if ( img1.empty() || img2.empty() )
|
||||
{
|
||||
cout << "Could not open or find the image!\n" << endl;
|
||||
parser.printMessage();
|
||||
return -1;
|
||||
}
|
||||
|
||||
//-- Step 1: Detect the keypoints using SURF Detector, compute the descriptors
|
||||
int minHessian = 400;
|
||||
Ptr<SURF> detector = SURF::create( minHessian );
|
||||
std::vector<KeyPoint> keypoints1, keypoints2;
|
||||
Mat descriptors1, descriptors2;
|
||||
detector->detectAndCompute( img1, noArray(), keypoints1, descriptors1 );
|
||||
detector->detectAndCompute( img2, noArray(), keypoints2, descriptors2 );
|
||||
|
||||
//-- Step 2: Matching descriptor vectors with a FLANN based matcher
|
||||
// Since SURF is a floating-point descriptor NORM_L2 is used
|
||||
Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create(DescriptorMatcher::FLANNBASED);
|
||||
std::vector< std::vector<DMatch> > knn_matches;
|
||||
matcher->knnMatch( descriptors1, descriptors2, knn_matches, 2 );
|
||||
|
||||
//-- Filter matches using the Lowe's ratio test
|
||||
const float ratio_thresh = 0.7f;
|
||||
std::vector<DMatch> good_matches;
|
||||
for (size_t i = 0; i < knn_matches.size(); i++)
|
||||
{
|
||||
if (knn_matches[i].size() > 1 && knn_matches[i][0].distance / knn_matches[i][1].distance <= ratio_thresh)
|
||||
{
|
||||
good_matches.push_back(knn_matches[i][0]);
|
||||
}
|
||||
}
|
||||
|
||||
//-- Draw matches
|
||||
Mat img_matches;
|
||||
drawMatches( img1, keypoints1, img2, keypoints2, good_matches, img_matches, Scalar::all(-1),
|
||||
Scalar::all(-1), std::vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );
|
||||
|
||||
//-- Show detected matches
|
||||
imshow("Good Matches", img_matches );
|
||||
|
||||
waitKey();
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
int main()
|
||||
{
|
||||
std::cout << "This tutorial code needs the xfeatures2d contrib module to be run." << std::endl;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
Executable
+107
@@ -0,0 +1,107 @@
|
||||
#include <iostream>
|
||||
#include "opencv2/core.hpp"
|
||||
#ifdef HAVE_OPENCV_XFEATURES2D
|
||||
#include "opencv2/calib3d.hpp"
|
||||
#include "opencv2/highgui.hpp"
|
||||
#include "opencv2/imgproc.hpp"
|
||||
#include "opencv2/features2d.hpp"
|
||||
#include "opencv2/xfeatures2d.hpp"
|
||||
|
||||
using namespace cv;
|
||||
using namespace cv::xfeatures2d;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
const char* keys =
|
||||
"{ help h | | Print help message. }"
|
||||
"{ input1 | ../data/box.png | Path to input image 1. }"
|
||||
"{ input2 | ../data/box_in_scene.png | Path to input image 2. }";
|
||||
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
CommandLineParser parser( argc, argv, keys );
|
||||
Mat img_object = imread( parser.get<String>("input1"), IMREAD_GRAYSCALE );
|
||||
Mat img_scene = imread( parser.get<String>("input2"), IMREAD_GRAYSCALE );
|
||||
if ( img_object.empty() || img_scene.empty() )
|
||||
{
|
||||
cout << "Could not open or find the image!\n" << endl;
|
||||
parser.printMessage();
|
||||
return -1;
|
||||
}
|
||||
|
||||
//-- Step 1: Detect the keypoints using SURF Detector, compute the descriptors
|
||||
int minHessian = 400;
|
||||
Ptr<SURF> detector = SURF::create( minHessian );
|
||||
std::vector<KeyPoint> keypoints_object, keypoints_scene;
|
||||
Mat descriptors_object, descriptors_scene;
|
||||
detector->detectAndCompute( img_object, noArray(), keypoints_object, descriptors_object );
|
||||
detector->detectAndCompute( img_scene, noArray(), keypoints_scene, descriptors_scene );
|
||||
|
||||
//-- Step 2: Matching descriptor vectors with a FLANN based matcher
|
||||
// Since SURF is a floating-point descriptor NORM_L2 is used
|
||||
Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create(DescriptorMatcher::FLANNBASED);
|
||||
std::vector< std::vector<DMatch> > knn_matches;
|
||||
matcher->knnMatch( descriptors_object, descriptors_scene, knn_matches, 2 );
|
||||
|
||||
//-- Filter matches using the Lowe's ratio test
|
||||
const float ratio_thresh = 0.75f;
|
||||
std::vector<DMatch> good_matches;
|
||||
for (size_t i = 0; i < knn_matches.size(); i++)
|
||||
{
|
||||
if (knn_matches[i].size() > 1 && knn_matches[i][0].distance / knn_matches[i][1].distance <= ratio_thresh)
|
||||
{
|
||||
good_matches.push_back(knn_matches[i][0]);
|
||||
}
|
||||
}
|
||||
|
||||
//-- Draw matches
|
||||
Mat img_matches;
|
||||
drawMatches( img_object, keypoints_object, img_scene, keypoints_scene, good_matches, img_matches, Scalar::all(-1),
|
||||
Scalar::all(-1), std::vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );
|
||||
|
||||
//-- Localize the object
|
||||
std::vector<Point2f> obj;
|
||||
std::vector<Point2f> scene;
|
||||
|
||||
for( size_t i = 0; i < good_matches.size(); i++ )
|
||||
{
|
||||
//-- Get the keypoints from the good matches
|
||||
obj.push_back( keypoints_object[ good_matches[i].queryIdx ].pt );
|
||||
scene.push_back( keypoints_scene[ good_matches[i].trainIdx ].pt );
|
||||
}
|
||||
|
||||
Mat H = findHomography( obj, scene, RANSAC );
|
||||
|
||||
//-- Get the corners from the image_1 ( the object to be "detected" )
|
||||
std::vector<Point2f> obj_corners(4);
|
||||
obj_corners[0] = Point2f(0, 0);
|
||||
obj_corners[1] = Point2f( (float)img_object.cols, 0 );
|
||||
obj_corners[2] = Point2f( (float)img_object.cols, (float)img_object.rows );
|
||||
obj_corners[3] = Point2f( 0, (float)img_object.rows );
|
||||
std::vector<Point2f> scene_corners(4);
|
||||
|
||||
perspectiveTransform( obj_corners, scene_corners, H);
|
||||
|
||||
//-- Draw lines between the corners (the mapped object in the scene - image_2 )
|
||||
line( img_matches, scene_corners[0] + Point2f((float)img_object.cols, 0),
|
||||
scene_corners[1] + Point2f((float)img_object.cols, 0), Scalar(0, 255, 0), 4 );
|
||||
line( img_matches, scene_corners[1] + Point2f((float)img_object.cols, 0),
|
||||
scene_corners[2] + Point2f((float)img_object.cols, 0), Scalar( 0, 255, 0), 4 );
|
||||
line( img_matches, scene_corners[2] + Point2f((float)img_object.cols, 0),
|
||||
scene_corners[3] + Point2f((float)img_object.cols, 0), Scalar( 0, 255, 0), 4 );
|
||||
line( img_matches, scene_corners[3] + Point2f((float)img_object.cols, 0),
|
||||
scene_corners[0] + Point2f((float)img_object.cols, 0), Scalar( 0, 255, 0), 4 );
|
||||
|
||||
//-- Show detected matches
|
||||
imshow("Good Matches & Object detection", img_matches );
|
||||
|
||||
waitKey();
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
int main()
|
||||
{
|
||||
std::cout << "This tutorial code needs the xfeatures2d contrib module to be run." << std::endl;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,33 @@
|
||||
#include <opencv2/imgproc.hpp>
|
||||
#include <opencv2/highgui.hpp>
|
||||
#include <math.h>
|
||||
|
||||
using namespace cv;
|
||||
using namespace std;
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
Mat img, gray;
|
||||
if( argc != 2 || !(img=imread(argv[1], 1)).data)
|
||||
return -1;
|
||||
cvtColor(img, gray, COLOR_BGR2GRAY);
|
||||
// smooth it, otherwise a lot of false circles may be detected
|
||||
GaussianBlur( gray, gray, Size(9, 9), 2, 2 );
|
||||
vector<Vec3f> circles;
|
||||
HoughCircles(gray, circles, HOUGH_GRADIENT,
|
||||
2, gray.rows/4, 200, 100 );
|
||||
for( size_t i = 0; i < circles.size(); i++ )
|
||||
{
|
||||
Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
|
||||
int radius = cvRound(circles[i][2]);
|
||||
// draw the circle center
|
||||
circle( img, center, 3, Scalar(0,255,0), -1, 8, 0 );
|
||||
// draw the circle outline
|
||||
circle( img, center, radius, Scalar(0,0,255), 3, 8, 0 );
|
||||
}
|
||||
namedWindow( "circles", 1 );
|
||||
imshow( "circles", img );
|
||||
|
||||
waitKey(0);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
#include <opencv2/imgproc.hpp>
|
||||
#include <opencv2/highgui.hpp>
|
||||
|
||||
using namespace cv;
|
||||
using namespace std;
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
Mat src, dst, color_dst;
|
||||
if( argc != 2 || !(src=imread(argv[1], 0)).data)
|
||||
return -1;
|
||||
|
||||
Canny( src, dst, 50, 200, 3 );
|
||||
cvtColor( dst, color_dst, COLOR_GRAY2BGR );
|
||||
|
||||
vector<Vec4i> lines;
|
||||
HoughLinesP( dst, lines, 1, CV_PI/180, 80, 30, 10 );
|
||||
for( size_t i = 0; i < lines.size(); i++ )
|
||||
{
|
||||
line( color_dst, Point(lines[i][0], lines[i][1]),
|
||||
Point( lines[i][2], lines[i][3]), Scalar(0,0,255), 3, 8 );
|
||||
}
|
||||
namedWindow( "Source", 1 );
|
||||
imshow( "Source", src );
|
||||
|
||||
namedWindow( "Detected Lines", 1 );
|
||||
imshow( "Detected Lines", color_dst );
|
||||
|
||||
waitKey(0);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
#include <opencv2/core.hpp>
|
||||
#include <opencv2/imgproc.hpp>
|
||||
#include <opencv2/imgcodecs.hpp>
|
||||
#include <opencv2/highgui.hpp>
|
||||
using namespace cv;
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main(int argc, const char *argv[])
|
||||
{
|
||||
// We need an input image. (can be grayscale or color)
|
||||
if (argc < 2)
|
||||
{
|
||||
cerr << "We need an image to process here. Please run: colorMap [path_to_image]" << endl;
|
||||
return -1;
|
||||
}
|
||||
Mat img_in = imread(argv[1]);
|
||||
if(img_in.empty())
|
||||
{
|
||||
cerr << "Sample image (" << argv[1] << ") is empty. Please adjust your path, so it points to a valid input image!" << endl;
|
||||
return -1;
|
||||
}
|
||||
// Holds the colormap version of the image:
|
||||
Mat img_color;
|
||||
// Apply the colormap:
|
||||
applyColorMap(img_in, img_color, COLORMAP_JET);
|
||||
// Show the result:
|
||||
imshow("colorMap", img_color);
|
||||
waitKey(0);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
#include <opencv2/imgproc.hpp>
|
||||
#include <opencv2/highgui.hpp>
|
||||
|
||||
using namespace cv;
|
||||
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
Mat src, hsv;
|
||||
if( argc != 2 || !(src=imread(argv[1], 1)).data )
|
||||
return -1;
|
||||
|
||||
cvtColor(src, hsv, COLOR_BGR2HSV);
|
||||
|
||||
// Quantize the hue to 30 levels
|
||||
// and the saturation to 32 levels
|
||||
int hbins = 30, sbins = 32;
|
||||
int histSize[] = {hbins, sbins};
|
||||
// hue varies from 0 to 179, see cvtColor
|
||||
float hranges[] = { 0, 180 };
|
||||
// saturation varies from 0 (black-gray-white) to
|
||||
// 255 (pure spectrum color)
|
||||
float sranges[] = { 0, 256 };
|
||||
const float* ranges[] = { hranges, sranges };
|
||||
MatND hist;
|
||||
// we compute the histogram from the 0-th and 1-st channels
|
||||
int channels[] = {0, 1};
|
||||
|
||||
calcHist( &hsv, 1, channels, Mat(), // do not use mask
|
||||
hist, 2, histSize, ranges,
|
||||
true, // the histogram is uniform
|
||||
false );
|
||||
double maxVal=0;
|
||||
minMaxLoc(hist, 0, &maxVal, 0, 0);
|
||||
|
||||
int scale = 10;
|
||||
Mat histImg = Mat::zeros(sbins*scale, hbins*10, CV_8UC3);
|
||||
|
||||
for( int h = 0; h < hbins; h++ )
|
||||
for( int s = 0; s < sbins; s++ )
|
||||
{
|
||||
float binVal = hist.at<float>(h, s);
|
||||
int intensity = cvRound(binVal*255/maxVal);
|
||||
rectangle( histImg, Point(h*scale, s*scale),
|
||||
Point( (h+1)*scale - 1, (s+1)*scale - 1),
|
||||
Scalar::all(intensity),
|
||||
-1 );
|
||||
}
|
||||
|
||||
namedWindow( "Source", 1 );
|
||||
imshow( "Source", src );
|
||||
|
||||
namedWindow( "H-S Histogram", 1 );
|
||||
imshow( "H-S Histogram", histImg );
|
||||
waitKey();
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
#include "opencv2/imgproc.hpp"
|
||||
#include "opencv2/highgui.hpp"
|
||||
|
||||
using namespace cv;
|
||||
using namespace std;
|
||||
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
Mat src;
|
||||
// the first command-line parameter must be a filename of the binary
|
||||
// (black-n-white) image
|
||||
if( argc != 2 || !(src=imread(argv[1], 0)).data)
|
||||
return -1;
|
||||
|
||||
Mat dst = Mat::zeros(src.rows, src.cols, CV_8UC3);
|
||||
|
||||
src = src > 1;
|
||||
namedWindow( "Source", 1 );
|
||||
imshow( "Source", src );
|
||||
|
||||
vector<vector<Point> > contours;
|
||||
vector<Vec4i> hierarchy;
|
||||
|
||||
findContours( src, contours, hierarchy,
|
||||
RETR_CCOMP, CHAIN_APPROX_SIMPLE );
|
||||
|
||||
// iterate through all the top-level contours,
|
||||
// draw each connected component with its own random color
|
||||
int idx = 0;
|
||||
for( ; idx >= 0; idx = hierarchy[idx][0] )
|
||||
{
|
||||
Scalar color( rand()&255, rand()&255, rand()&255 );
|
||||
drawContours( dst, contours, idx, color, FILLED, 8, hierarchy );
|
||||
}
|
||||
|
||||
namedWindow( "Components", 1 );
|
||||
imshow( "Components", dst );
|
||||
waitKey(0);
|
||||
}
|
||||
@@ -11,8 +11,10 @@
|
||||
| [SSDs from TensorFlow](https://github.com/tensorflow/models/tree/master/research/object_detection/) | `0.00784 (2/255)` | `300x300` | `127.5 127.5 127.5` | RGB |
|
||||
| [YOLO](https://pjreddie.com/darknet/yolo/) | `0.00392 (1/255)` | `416x416` | `0 0 0` | RGB |
|
||||
| [VGG16-SSD](https://github.com/weiliu89/caffe/tree/ssd) | `1.0` | `300x300` | `104 117 123` | BGR |
|
||||
| [Faster-RCNN](https://github.com/rbgirshick/py-faster-rcnn) | `1.0` | `800x600` | `102.9801, 115.9465, 122.7717` | BGR |
|
||||
| [Faster-RCNN](https://github.com/rbgirshick/py-faster-rcnn) | `1.0` | `800x600` | `102.9801 115.9465 122.7717` | BGR |
|
||||
| [R-FCN](https://github.com/YuwenXiong/py-R-FCN) | `1.0` | `800x600` | `102.9801 115.9465 122.7717` | BGR |
|
||||
| [Faster-RCNN, ResNet backbone](https://github.com/tensorflow/models/tree/master/research/object_detection/) | `1.0` | `300x300` | `103.939 116.779 123.68` | RGB |
|
||||
| [Faster-RCNN, InceptionV2 backbone](https://github.com/tensorflow/models/tree/master/research/object_detection/) | `0.00784 (2/255)` | `300x300` | `127.5 127.5 127.5` | RGB |
|
||||
|
||||
#### Face detection
|
||||
[An origin model](https://github.com/opencv/opencv/tree/master/samples/dnn/face_detector)
|
||||
|
||||
@@ -23,7 +23,7 @@ const char* keys =
|
||||
"{ backend | 0 | Choose one of computation backends: "
|
||||
"0: default C++ backend, "
|
||||
"1: Halide language (http://halide-lang.org/), "
|
||||
"2: Intel's Deep Learning Inference Engine (https://software.seek.intel.com/deep-learning-deployment)}"
|
||||
"2: Intel's Deep Learning Inference Engine (https://software.intel.com/openvino-toolkit)}"
|
||||
"{ target | 0 | Choose one of target computation devices: "
|
||||
"0: CPU target (by default),"
|
||||
"1: OpenCL }";
|
||||
|
||||
@@ -34,7 +34,7 @@ parser.add_argument('--backend', choices=backends, default=cv.dnn.DNN_BACKEND_DE
|
||||
help="Choose one of computation backends: "
|
||||
"%d: default C++ backend, "
|
||||
"%d: Halide language (http://halide-lang.org/), "
|
||||
"%d: Intel's Deep Learning Inference Engine (https://software.seek.intel.com/deep-learning-deployment)" % backends)
|
||||
"%d: Intel's Deep Learning Inference Engine (https://software.intel.com/openvino-toolkit)" % backends)
|
||||
parser.add_argument('--target', choices=targets, default=cv.dnn.DNN_TARGET_CPU, type=int,
|
||||
help='Choose one of target computation devices: '
|
||||
'%d: CPU target (by default), '
|
||||
|
||||
@@ -13,7 +13,7 @@ The data preparation pipeline can be represented as:
|
||||
a) Find some datasets with face bounding boxes annotation. For some reasons I can't provide links here, but you easily find them on your own. Also study the data. It may contain small or low quality faces which can spoil training process. Often there are special flags about object quality in annotation. Remove such faces from annotation (smaller when 16 along at least one side, or blurred, of highly-occluded, or something else).
|
||||
|
||||
b) The downloaded dataset will have some format of annotation. It may be one single file for all images, or separate file for each image or something else. But to train SSD in Caffe you need to convert annotation to PASCAL VOC format.
|
||||
PASCAL VOC annoitation consist of .xml file for each image. In this xml file all face bounding boxes should be listed as:
|
||||
PASCAL VOC annotation consist of .xml file for each image. In this xml file all face bounding boxes should be listed as:
|
||||
|
||||
<annotation>
|
||||
<size>
|
||||
@@ -42,7 +42,7 @@ PASCAL VOC annoitation consist of .xml file for each image. In this xml file all
|
||||
</object>
|
||||
</annotation>
|
||||
|
||||
So, convert your dataset's annotation to the fourmat above.
|
||||
So, convert your dataset's annotation to the format above.
|
||||
Also, you should create labelmap.prototxt file with the following content:
|
||||
item {
|
||||
name: "none_of_the_above"
|
||||
@@ -76,4 +76,4 @@ mkdir -p log
|
||||
/path_for_caffe_build_dir/tools/caffe train -solver="solver.prototxt" -gpu 0 2>&1 | tee -a log/log.log
|
||||
|
||||
And wait. It will take about 8 hours to finish the process.
|
||||
After it you can use your .caffemodel from snapshot/ subdirectory in resnet_face_ssd_python.py sample.
|
||||
After it you can use your .caffemodel from snapshot/ subdirectory in resnet_face_ssd_python.py sample.
|
||||
|
||||
@@ -25,7 +25,7 @@ const char* keys =
|
||||
"{ backend | 0 | Choose one of computation backends: "
|
||||
"0: default C++ backend, "
|
||||
"1: Halide language (http://halide-lang.org/), "
|
||||
"2: Intel's Deep Learning Inference Engine (https://software.seek.intel.com/deep-learning-deployment)}"
|
||||
"2: Intel's Deep Learning Inference Engine (https://software.intel.com/openvino-toolkit)}"
|
||||
"{ target | 0 | Choose one of target computation devices: "
|
||||
"0: CPU target (by default),"
|
||||
"1: OpenCL }";
|
||||
|
||||
@@ -35,7 +35,7 @@ parser.add_argument('--backend', choices=backends, default=cv.dnn.DNN_BACKEND_DE
|
||||
help="Choose one of computation backends: "
|
||||
"%d: default C++ backend, "
|
||||
"%d: Halide language (http://halide-lang.org/), "
|
||||
"%d: Intel's Deep Learning Inference Engine (https://software.seek.intel.com/deep-learning-deployment)" % backends)
|
||||
"%d: Intel's Deep Learning Inference Engine (https://software.intel.com/openvino-toolkit)" % backends)
|
||||
parser.add_argument('--target', choices=targets, default=cv.dnn.DNN_TARGET_CPU, type=int,
|
||||
help='Choose one of target computation devices: '
|
||||
'%d: CPU target (by default), '
|
||||
@@ -174,7 +174,7 @@ while cv.waitKey(1) < 0:
|
||||
net.setInput(blob)
|
||||
if net.getLayer(0).outputNameToIndex('im_info') != -1: # Faster-RCNN or R-FCN
|
||||
frame = cv.resize(frame, (inpWidth, inpHeight))
|
||||
net.setInput(np.array([inpHeight, inpWidth, 1.6], dtype=np.float32), 'im_info');
|
||||
net.setInput(np.array([inpHeight, inpWidth, 1.6], dtype=np.float32), 'im_info')
|
||||
outs = net.forward(getOutputsNames(net))
|
||||
|
||||
postprocess(frame, outs)
|
||||
|
||||
@@ -26,7 +26,7 @@ const char* keys =
|
||||
"{ backend | 0 | Choose one of computation backends: "
|
||||
"0: default C++ backend, "
|
||||
"1: Halide language (http://halide-lang.org/), "
|
||||
"2: Intel's Deep Learning Inference Engine (https://software.seek.intel.com/deep-learning-deployment)}"
|
||||
"2: Intel's Deep Learning Inference Engine (https://software.intel.com/openvino-toolkit)}"
|
||||
"{ target | 0 | Choose one of target computation devices: "
|
||||
"0: CPU target (by default),"
|
||||
"1: OpenCL }";
|
||||
|
||||
@@ -36,7 +36,7 @@ parser.add_argument('--backend', choices=backends, default=cv.dnn.DNN_BACKEND_DE
|
||||
help="Choose one of computation backends: "
|
||||
"%d: default C++ backend, "
|
||||
"%d: Halide language (http://halide-lang.org/), "
|
||||
"%d: Intel's Deep Learning Inference Engine (https://software.seek.intel.com/deep-learning-deployment)" % backends)
|
||||
"%d: Intel's Deep Learning Inference Engine (https://software.intel.com/openvino-toolkit)" % backends)
|
||||
parser.add_argument('--target', choices=targets, default=cv.dnn.DNN_TARGET_CPU, type=int,
|
||||
help='Choose one of target computation devices: '
|
||||
'%d: CPU target (by default), '
|
||||
|
||||
@@ -0,0 +1,291 @@
|
||||
import argparse
|
||||
import numpy as np
|
||||
import tensorflow as tf
|
||||
|
||||
from tensorflow.core.framework.node_def_pb2 import NodeDef
|
||||
from tensorflow.tools.graph_transforms import TransformGraph
|
||||
from google.protobuf import text_format
|
||||
|
||||
parser = argparse.ArgumentParser(description='Run this script to get a text graph of '
|
||||
'SSD model from TensorFlow Object Detection API. '
|
||||
'Then pass it with .pb file to cv::dnn::readNetFromTensorflow function.')
|
||||
parser.add_argument('--input', required=True, help='Path to frozen TensorFlow graph.')
|
||||
parser.add_argument('--output', required=True, help='Path to output text graph.')
|
||||
parser.add_argument('--num_classes', default=90, type=int, help='Number of trained classes.')
|
||||
parser.add_argument('--scales', default=[0.25, 0.5, 1.0, 2.0], type=float, nargs='+',
|
||||
help='Hyper-parameter of grid_anchor_generator from a config file.')
|
||||
parser.add_argument('--aspect_ratios', default=[0.5, 1.0, 2.0], type=float, nargs='+',
|
||||
help='Hyper-parameter of grid_anchor_generator from a config file.')
|
||||
parser.add_argument('--features_stride', default=16, type=float, nargs='+',
|
||||
help='Hyper-parameter from a config file.')
|
||||
args = parser.parse_args()
|
||||
|
||||
scopesToKeep = ('FirstStageFeatureExtractor', 'Conv',
|
||||
'FirstStageBoxPredictor/BoxEncodingPredictor',
|
||||
'FirstStageBoxPredictor/ClassPredictor',
|
||||
'CropAndResize',
|
||||
'MaxPool2D',
|
||||
'SecondStageFeatureExtractor',
|
||||
'SecondStageBoxPredictor',
|
||||
'image_tensor')
|
||||
|
||||
scopesToIgnore = ('FirstStageFeatureExtractor/Assert',
|
||||
'FirstStageFeatureExtractor/Shape',
|
||||
'FirstStageFeatureExtractor/strided_slice',
|
||||
'FirstStageFeatureExtractor/GreaterEqual',
|
||||
'FirstStageFeatureExtractor/LogicalAnd')
|
||||
|
||||
unusedAttrs = ['T', 'Tshape', 'N', 'Tidx', 'Tdim', 'use_cudnn_on_gpu',
|
||||
'Index', 'Tperm', 'is_training', 'Tpaddings']
|
||||
|
||||
# Read the graph.
|
||||
with tf.gfile.FastGFile(args.input, 'rb') as f:
|
||||
graph_def = tf.GraphDef()
|
||||
graph_def.ParseFromString(f.read())
|
||||
|
||||
# Removes Identity nodes
|
||||
def removeIdentity():
|
||||
identities = {}
|
||||
for node in graph_def.node:
|
||||
if node.op == 'Identity':
|
||||
identities[node.name] = node.input[0]
|
||||
graph_def.node.remove(node)
|
||||
|
||||
for node in graph_def.node:
|
||||
for i in range(len(node.input)):
|
||||
if node.input[i] in identities:
|
||||
node.input[i] = identities[node.input[i]]
|
||||
|
||||
removeIdentity()
|
||||
|
||||
removedNodes = []
|
||||
|
||||
for i in reversed(range(len(graph_def.node))):
|
||||
op = graph_def.node[i].op
|
||||
name = graph_def.node[i].name
|
||||
|
||||
if op == 'Const' or name.startswith(scopesToIgnore) or not name.startswith(scopesToKeep):
|
||||
if op != 'Const':
|
||||
removedNodes.append(name)
|
||||
|
||||
del graph_def.node[i]
|
||||
else:
|
||||
for attr in unusedAttrs:
|
||||
if attr in graph_def.node[i].attr:
|
||||
del graph_def.node[i].attr[attr]
|
||||
|
||||
# Remove references to removed nodes except Const nodes.
|
||||
for node in graph_def.node:
|
||||
for i in reversed(range(len(node.input))):
|
||||
if node.input[i] in removedNodes:
|
||||
del node.input[i]
|
||||
|
||||
|
||||
# Connect input node to the first layer
|
||||
assert(graph_def.node[0].op == 'Placeholder')
|
||||
graph_def.node[1].input.insert(0, graph_def.node[0].name)
|
||||
|
||||
# Temporarily remove top nodes.
|
||||
topNodes = []
|
||||
while True:
|
||||
node = graph_def.node.pop()
|
||||
topNodes.append(node)
|
||||
if node.op == 'CropAndResize':
|
||||
break
|
||||
|
||||
def tensorMsg(values):
|
||||
if all([isinstance(v, float) for v in values]):
|
||||
dtype = 'DT_FLOAT'
|
||||
field = 'float_val'
|
||||
elif all([isinstance(v, int) for v in values]):
|
||||
dtype = 'DT_INT32'
|
||||
field = 'int_val'
|
||||
else:
|
||||
raise Exception('Wrong values types')
|
||||
|
||||
msg = 'tensor { dtype: ' + dtype + ' tensor_shape { dim { size: %d } }' % len(values)
|
||||
for value in values:
|
||||
msg += '%s: %s ' % (field, str(value))
|
||||
return msg + '}'
|
||||
|
||||
def addSlice(inp, out, begins, sizes):
|
||||
beginsNode = NodeDef()
|
||||
beginsNode.name = out + '/begins'
|
||||
beginsNode.op = 'Const'
|
||||
text_format.Merge(tensorMsg(begins), beginsNode.attr["value"])
|
||||
graph_def.node.extend([beginsNode])
|
||||
|
||||
sizesNode = NodeDef()
|
||||
sizesNode.name = out + '/sizes'
|
||||
sizesNode.op = 'Const'
|
||||
text_format.Merge(tensorMsg(sizes), sizesNode.attr["value"])
|
||||
graph_def.node.extend([sizesNode])
|
||||
|
||||
sliced = NodeDef()
|
||||
sliced.name = out
|
||||
sliced.op = 'Slice'
|
||||
sliced.input.append(inp)
|
||||
sliced.input.append(beginsNode.name)
|
||||
sliced.input.append(sizesNode.name)
|
||||
graph_def.node.extend([sliced])
|
||||
|
||||
def addReshape(inp, out, shape):
|
||||
shapeNode = NodeDef()
|
||||
shapeNode.name = out + '/shape'
|
||||
shapeNode.op = 'Const'
|
||||
text_format.Merge(tensorMsg(shape), shapeNode.attr["value"])
|
||||
graph_def.node.extend([shapeNode])
|
||||
|
||||
reshape = NodeDef()
|
||||
reshape.name = out
|
||||
reshape.op = 'Reshape'
|
||||
reshape.input.append(inp)
|
||||
reshape.input.append(shapeNode.name)
|
||||
graph_def.node.extend([reshape])
|
||||
|
||||
def addSoftMax(inp, out):
|
||||
softmax = NodeDef()
|
||||
softmax.name = out
|
||||
softmax.op = 'Softmax'
|
||||
text_format.Merge('i: -1', softmax.attr['axis'])
|
||||
softmax.input.append(inp)
|
||||
graph_def.node.extend([softmax])
|
||||
|
||||
addReshape('FirstStageBoxPredictor/ClassPredictor/BiasAdd',
|
||||
'FirstStageBoxPredictor/ClassPredictor/reshape_1', [0, -1, 2])
|
||||
|
||||
addSoftMax('FirstStageBoxPredictor/ClassPredictor/reshape_1',
|
||||
'FirstStageBoxPredictor/ClassPredictor/softmax') # Compare with Reshape_4
|
||||
|
||||
flatten = NodeDef()
|
||||
flatten.name = 'FirstStageBoxPredictor/BoxEncodingPredictor/flatten' # Compare with FirstStageBoxPredictor/BoxEncodingPredictor/BiasAdd
|
||||
flatten.op = 'Flatten'
|
||||
flatten.input.append('FirstStageBoxPredictor/BoxEncodingPredictor/BiasAdd')
|
||||
graph_def.node.extend([flatten])
|
||||
|
||||
proposals = NodeDef()
|
||||
proposals.name = 'proposals' # Compare with ClipToWindow/Gather/Gather (NOTE: normalized)
|
||||
proposals.op = 'PriorBox'
|
||||
proposals.input.append('FirstStageBoxPredictor/BoxEncodingPredictor/BiasAdd')
|
||||
proposals.input.append(graph_def.node[0].name) # image_tensor
|
||||
|
||||
text_format.Merge('b: false', proposals.attr["flip"])
|
||||
text_format.Merge('b: true', proposals.attr["clip"])
|
||||
text_format.Merge('f: %f' % args.features_stride, proposals.attr["step"])
|
||||
text_format.Merge('f: 0.0', proposals.attr["offset"])
|
||||
text_format.Merge(tensorMsg([0.1, 0.1, 0.2, 0.2]), proposals.attr["variance"])
|
||||
|
||||
widths = []
|
||||
heights = []
|
||||
for a in args.aspect_ratios:
|
||||
for s in args.scales:
|
||||
ar = np.sqrt(a)
|
||||
heights.append((args.features_stride**2) * s / ar)
|
||||
widths.append((args.features_stride**2) * s * ar)
|
||||
|
||||
text_format.Merge(tensorMsg(widths), proposals.attr["width"])
|
||||
text_format.Merge(tensorMsg(heights), proposals.attr["height"])
|
||||
|
||||
graph_def.node.extend([proposals])
|
||||
|
||||
# Compare with Reshape_5
|
||||
detectionOut = NodeDef()
|
||||
detectionOut.name = 'detection_out'
|
||||
detectionOut.op = 'DetectionOutput'
|
||||
|
||||
detectionOut.input.append('FirstStageBoxPredictor/BoxEncodingPredictor/flatten')
|
||||
detectionOut.input.append('FirstStageBoxPredictor/ClassPredictor/softmax')
|
||||
detectionOut.input.append('proposals')
|
||||
|
||||
text_format.Merge('i: 2', detectionOut.attr['num_classes'])
|
||||
text_format.Merge('b: true', detectionOut.attr['share_location'])
|
||||
text_format.Merge('i: 0', detectionOut.attr['background_label_id'])
|
||||
text_format.Merge('f: 0.7', detectionOut.attr['nms_threshold'])
|
||||
text_format.Merge('i: 6000', detectionOut.attr['top_k'])
|
||||
text_format.Merge('s: "CENTER_SIZE"', detectionOut.attr['code_type'])
|
||||
text_format.Merge('i: 100', detectionOut.attr['keep_top_k'])
|
||||
text_format.Merge('b: true', detectionOut.attr['clip'])
|
||||
text_format.Merge('b: true', detectionOut.attr['loc_pred_transposed'])
|
||||
|
||||
graph_def.node.extend([detectionOut])
|
||||
|
||||
# Save as text.
|
||||
for node in reversed(topNodes):
|
||||
graph_def.node.extend([node])
|
||||
|
||||
addSoftMax('SecondStageBoxPredictor/Reshape_1', 'SecondStageBoxPredictor/Reshape_1/softmax')
|
||||
|
||||
addSlice('SecondStageBoxPredictor/Reshape_1/softmax',
|
||||
'SecondStageBoxPredictor/Reshape_1/slice',
|
||||
[0, 0, 1], [-1, -1, -1])
|
||||
|
||||
addReshape('SecondStageBoxPredictor/Reshape_1/slice',
|
||||
'SecondStageBoxPredictor/Reshape_1/Reshape', [1, -1])
|
||||
|
||||
# Replace Flatten subgraph onto a single node.
|
||||
for i in reversed(range(len(graph_def.node))):
|
||||
if graph_def.node[i].op == 'CropAndResize':
|
||||
graph_def.node[i].input.insert(1, 'detection_out')
|
||||
|
||||
if graph_def.node[i].name == 'SecondStageBoxPredictor/Reshape':
|
||||
shapeNode = NodeDef()
|
||||
shapeNode.name = 'SecondStageBoxPredictor/Reshape/shape2'
|
||||
shapeNode.op = 'Const'
|
||||
text_format.Merge(tensorMsg([1, -1, 4]), shapeNode.attr["value"])
|
||||
graph_def.node.extend([shapeNode])
|
||||
|
||||
graph_def.node[i].input.pop()
|
||||
graph_def.node[i].input.append(shapeNode.name)
|
||||
|
||||
if graph_def.node[i].name in ['SecondStageBoxPredictor/Flatten/flatten/Shape',
|
||||
'SecondStageBoxPredictor/Flatten/flatten/strided_slice',
|
||||
'SecondStageBoxPredictor/Flatten/flatten/Reshape/shape']:
|
||||
del graph_def.node[i]
|
||||
|
||||
for node in graph_def.node:
|
||||
if node.name == 'SecondStageBoxPredictor/Flatten/flatten/Reshape':
|
||||
node.op = 'Flatten'
|
||||
node.input.pop()
|
||||
break
|
||||
|
||||
################################################################################
|
||||
### Postprocessing
|
||||
################################################################################
|
||||
addSlice('detection_out', 'detection_out/slice', [0, 0, 0, 3], [-1, -1, -1, 4])
|
||||
|
||||
variance = NodeDef()
|
||||
variance.name = 'proposals/variance'
|
||||
variance.op = 'Const'
|
||||
text_format.Merge(tensorMsg([0.1, 0.1, 0.2, 0.2]), variance.attr["value"])
|
||||
graph_def.node.extend([variance])
|
||||
|
||||
varianceEncoder = NodeDef()
|
||||
varianceEncoder.name = 'variance_encoded'
|
||||
varianceEncoder.op = 'Mul'
|
||||
varianceEncoder.input.append('SecondStageBoxPredictor/Reshape')
|
||||
varianceEncoder.input.append(variance.name)
|
||||
text_format.Merge('i: 2', varianceEncoder.attr["axis"])
|
||||
graph_def.node.extend([varianceEncoder])
|
||||
|
||||
addReshape('detection_out/slice', 'detection_out/slice/reshape', [1, 1, -1])
|
||||
|
||||
detectionOut = NodeDef()
|
||||
detectionOut.name = 'detection_out_final'
|
||||
detectionOut.op = 'DetectionOutput'
|
||||
|
||||
detectionOut.input.append('variance_encoded')
|
||||
detectionOut.input.append('SecondStageBoxPredictor/Reshape_1/Reshape')
|
||||
detectionOut.input.append('detection_out/slice/reshape')
|
||||
|
||||
text_format.Merge('i: %d' % args.num_classes, detectionOut.attr['num_classes'])
|
||||
text_format.Merge('b: false', detectionOut.attr['share_location'])
|
||||
text_format.Merge('i: %d' % (args.num_classes + 1), detectionOut.attr['background_label_id'])
|
||||
text_format.Merge('f: 0.6', detectionOut.attr['nms_threshold'])
|
||||
text_format.Merge('s: "CENTER_SIZE"', detectionOut.attr['code_type'])
|
||||
text_format.Merge('i: 100', detectionOut.attr['keep_top_k'])
|
||||
text_format.Merge('b: true', detectionOut.attr['loc_pred_transposed'])
|
||||
text_format.Merge('b: true', detectionOut.attr['clip'])
|
||||
text_format.Merge('b: true', detectionOut.attr['variance_encoded_in_target'])
|
||||
graph_def.node.extend([detectionOut])
|
||||
|
||||
tf.train.write_graph(graph_def, "", args.output, as_text=True)
|
||||
@@ -0,0 +1,158 @@
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Container;
|
||||
import java.awt.Image;
|
||||
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.core.TermCriteria;
|
||||
import org.opencv.highgui.HighGui;
|
||||
import org.opencv.imgcodecs.Imgcodecs;
|
||||
import org.opencv.imgproc.Imgproc;
|
||||
|
||||
class CornerSubPix {
|
||||
private Mat src = new Mat();
|
||||
private Mat srcGray = new Mat();
|
||||
private JFrame frame;
|
||||
private JLabel imgLabel;
|
||||
private static final int MAX_CORNERS = 25;
|
||||
private int maxCorners = 10;
|
||||
private Random rng = new Random(12345);
|
||||
|
||||
public CornerSubPix(String[] args) {
|
||||
/// Load source image and convert it to gray
|
||||
String filename = args.length > 0 ? args[0] : "../data/pic3.png";
|
||||
src = Imgcodecs.imread(filename);
|
||||
if (src.empty()) {
|
||||
System.err.println("Cannot read image: " + filename);
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
Imgproc.cvtColor(src, srcGray, Imgproc.COLOR_BGR2GRAY);
|
||||
|
||||
// Create and set up the window.
|
||||
frame = new JFrame("Shi-Tomasi corner detector 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("Max corners:"));
|
||||
JSlider slider = new JSlider(0, MAX_CORNERS, maxCorners);
|
||||
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();
|
||||
maxCorners = source.getValue();
|
||||
update();
|
||||
}
|
||||
});
|
||||
sliderPanel.add(slider);
|
||||
pane.add(sliderPanel, BorderLayout.PAGE_START);
|
||||
|
||||
imgLabel = new JLabel(new ImageIcon(img));
|
||||
pane.add(imgLabel, BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
private void update() {
|
||||
/// Parameters for Shi-Tomasi algorithm
|
||||
maxCorners = Math.max(maxCorners, 1);
|
||||
MatOfPoint corners = new MatOfPoint();
|
||||
double qualityLevel = 0.01;
|
||||
double minDistance = 10;
|
||||
int blockSize = 3, gradientSize = 3;
|
||||
boolean useHarrisDetector = false;
|
||||
double k = 0.04;
|
||||
|
||||
/// Copy the source image
|
||||
Mat copy = src.clone();
|
||||
|
||||
/// Apply corner detection
|
||||
Imgproc.goodFeaturesToTrack(srcGray, corners, maxCorners, qualityLevel, minDistance, new Mat(),
|
||||
blockSize, gradientSize, useHarrisDetector, k);
|
||||
|
||||
/// Draw corners detected
|
||||
System.out.println("** Number of corners detected: " + corners.rows());
|
||||
int[] cornersData = new int[(int) (corners.total() * corners.channels())];
|
||||
corners.get(0, 0, cornersData);
|
||||
int radius = 4;
|
||||
Mat matCorners = new Mat(corners.rows(), 2, CvType.CV_32F);
|
||||
float[] matCornersData = new float[(int) (matCorners.total() * matCorners.channels())];
|
||||
matCorners.get(0, 0, matCornersData);
|
||||
for (int i = 0; i < corners.rows(); i++) {
|
||||
Imgproc.circle(copy, new Point(cornersData[i * 2], cornersData[i * 2 + 1]), radius,
|
||||
new Scalar(rng.nextInt(256), rng.nextInt(256), rng.nextInt(256)), Core.FILLED);
|
||||
matCornersData[i * 2] = cornersData[i * 2];
|
||||
matCornersData[i * 2 + 1] = cornersData[i * 2 + 1];
|
||||
}
|
||||
matCorners.put(0, 0, matCornersData);
|
||||
|
||||
imgLabel.setIcon(new ImageIcon(HighGui.toBufferedImage(copy)));
|
||||
frame.repaint();
|
||||
|
||||
/// Set the needed parameters to find the refined corners
|
||||
Size winSize = new Size(5, 5);
|
||||
Size zeroZone = new Size(-1, -1);
|
||||
TermCriteria criteria = new TermCriteria(TermCriteria.EPS + TermCriteria.COUNT, 40, 0.001);
|
||||
|
||||
/// Calculate the refined corner locations
|
||||
Imgproc.cornerSubPix(srcGray, matCorners, winSize, zeroZone, criteria);
|
||||
|
||||
/// Write them down
|
||||
matCorners.get(0, 0, matCornersData);
|
||||
for (int i = 0; i < corners.rows(); i++) {
|
||||
System.out.println(
|
||||
" -- Refined Corner [" + i + "] (" + matCornersData[i * 2] + "," + matCornersData[i * 2 + 1] + ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class CornerSubPixDemo {
|
||||
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 CornerSubPix(args);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
+190
@@ -0,0 +1,190 @@
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Container;
|
||||
import java.awt.Image;
|
||||
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.Core.MinMaxLocResult;
|
||||
import org.opencv.core.CvType;
|
||||
import org.opencv.core.Mat;
|
||||
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 CornerDetector {
|
||||
private Mat src = new Mat();
|
||||
private Mat srcGray = new Mat();
|
||||
private Mat harrisDst = new Mat();
|
||||
private Mat shiTomasiDst = new Mat();
|
||||
private Mat harrisCopy = new Mat();
|
||||
private Mat shiTomasiCopy = new Mat();
|
||||
private Mat Mc = new Mat();
|
||||
private JFrame frame;
|
||||
private JLabel harrisImgLabel;
|
||||
private JLabel shiTomasiImgLabel;
|
||||
private static final int MAX_QUALITY_LEVEL = 100;
|
||||
private int qualityLevel = 50;
|
||||
private double harrisMinVal;
|
||||
private double harrisMaxVal;
|
||||
private double shiTomasiMinVal;
|
||||
private double shiTomasiMaxVal;
|
||||
private Random rng = new Random(12345);
|
||||
|
||||
public CornerDetector(String[] args) {
|
||||
/// Load source image and convert it to gray
|
||||
String filename = args.length > 0 ? args[0] : "../data/building.jpg";
|
||||
src = Imgcodecs.imread(filename);
|
||||
if (src.empty()) {
|
||||
System.err.println("Cannot read image: " + filename);
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
Imgproc.cvtColor(src, srcGray, Imgproc.COLOR_BGR2GRAY);
|
||||
|
||||
// Create and set up the window.
|
||||
frame = new JFrame("Creating your own corner detector 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);
|
||||
|
||||
/// Set some parameters
|
||||
int blockSize = 3, apertureSize = 3;
|
||||
|
||||
/// My Harris matrix -- Using cornerEigenValsAndVecs
|
||||
Imgproc.cornerEigenValsAndVecs(srcGray, harrisDst, blockSize, apertureSize);
|
||||
|
||||
/* calculate Mc */
|
||||
Mc = Mat.zeros(srcGray.size(), CvType.CV_32F);
|
||||
|
||||
float[] harrisData = new float[(int) (harrisDst.total() * harrisDst.channels())];
|
||||
harrisDst.get(0, 0, harrisData);
|
||||
float[] McData = new float[(int) (Mc.total() * Mc.channels())];
|
||||
Mc.get(0, 0, McData);
|
||||
|
||||
for( int i = 0; i < srcGray.rows(); i++ ) {
|
||||
for( int j = 0; j < srcGray.cols(); j++ ) {
|
||||
float lambda1 = harrisData[(i*srcGray.cols() + j) * 6];
|
||||
float lambda2 = harrisData[(i*srcGray.cols() + j) * 6 + 1];
|
||||
McData[i*srcGray.cols()+j] = (float) (lambda1*lambda2 - 0.04f*Math.pow( ( lambda1 + lambda2 ), 2 ));
|
||||
}
|
||||
}
|
||||
Mc.put(0, 0, McData);
|
||||
|
||||
MinMaxLocResult res = Core.minMaxLoc(Mc);
|
||||
harrisMinVal = res.minVal;
|
||||
harrisMaxVal = res.maxVal;
|
||||
|
||||
/// My Shi-Tomasi -- Using cornerMinEigenVal
|
||||
Imgproc.cornerMinEigenVal(srcGray, shiTomasiDst, blockSize, apertureSize);
|
||||
res = Core.minMaxLoc(shiTomasiDst);
|
||||
shiTomasiMinVal = res.minVal;
|
||||
shiTomasiMaxVal = res.maxVal;
|
||||
|
||||
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("Max corners:"));
|
||||
JSlider slider = new JSlider(0, MAX_QUALITY_LEVEL, qualityLevel);
|
||||
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();
|
||||
qualityLevel = source.getValue();
|
||||
update();
|
||||
}
|
||||
});
|
||||
sliderPanel.add(slider);
|
||||
pane.add(sliderPanel, BorderLayout.PAGE_START);
|
||||
|
||||
JPanel imgPanel = new JPanel();
|
||||
harrisImgLabel = new JLabel(new ImageIcon(img));
|
||||
shiTomasiImgLabel = new JLabel(new ImageIcon(img));
|
||||
imgPanel.add(harrisImgLabel);
|
||||
imgPanel.add(shiTomasiImgLabel);
|
||||
pane.add(imgPanel, BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
private void update() {
|
||||
int qualityLevelVal = Math.max(qualityLevel, 1);
|
||||
|
||||
//Harris
|
||||
harrisCopy = src.clone();
|
||||
|
||||
float[] McData = new float[(int) (Mc.total() * Mc.channels())];
|
||||
Mc.get(0, 0, McData);
|
||||
for (int i = 0; i < srcGray.rows(); i++) {
|
||||
for (int j = 0; j < srcGray.cols(); j++) {
|
||||
if (McData[i * srcGray.cols() + j] > harrisMinVal
|
||||
+ (harrisMaxVal - harrisMinVal) * qualityLevelVal / MAX_QUALITY_LEVEL) {
|
||||
Imgproc.circle(harrisCopy, new Point(j, i), 4,
|
||||
new Scalar(rng.nextInt(256), rng.nextInt(256), rng.nextInt(256)), Core.FILLED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Shi-Tomasi
|
||||
shiTomasiCopy = src.clone();
|
||||
|
||||
float[] shiTomasiData = new float[(int) (shiTomasiDst.total() * shiTomasiDst.channels())];
|
||||
shiTomasiDst.get(0, 0, shiTomasiData);
|
||||
for (int i = 0; i < srcGray.rows(); i++) {
|
||||
for (int j = 0; j < srcGray.cols(); j++) {
|
||||
if (shiTomasiData[i * srcGray.cols() + j] > shiTomasiMinVal
|
||||
+ (shiTomasiMaxVal - shiTomasiMinVal) * qualityLevelVal / MAX_QUALITY_LEVEL) {
|
||||
Imgproc.circle(shiTomasiCopy, new Point(j, i), 4,
|
||||
new Scalar(rng.nextInt(256), rng.nextInt(256), rng.nextInt(256)), Core.FILLED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
harrisImgLabel.setIcon(new ImageIcon(HighGui.toBufferedImage(harrisCopy)));
|
||||
shiTomasiImgLabel.setIcon(new ImageIcon(HighGui.toBufferedImage(shiTomasiCopy)));
|
||||
frame.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
public class CornerDetectorDemo {
|
||||
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 CornerDetector(args);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
+134
@@ -0,0 +1,134 @@
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Container;
|
||||
import java.awt.Image;
|
||||
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.Mat;
|
||||
import org.opencv.core.MatOfPoint;
|
||||
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 GoodFeaturesToTrack {
|
||||
private Mat src = new Mat();
|
||||
private Mat srcGray = new Mat();
|
||||
private JFrame frame;
|
||||
private JLabel imgLabel;
|
||||
private static final int MAX_THRESHOLD = 100;
|
||||
private int maxCorners = 23;
|
||||
private Random rng = new Random(12345);
|
||||
|
||||
public GoodFeaturesToTrack(String[] args) {
|
||||
/// Load source image and convert it to gray
|
||||
String filename = args.length > 0 ? args[0] : "../data/pic3.png";
|
||||
src = Imgcodecs.imread(filename);
|
||||
if (src.empty()) {
|
||||
System.err.println("Cannot read image: " + filename);
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
Imgproc.cvtColor(src, srcGray, Imgproc.COLOR_BGR2GRAY);
|
||||
|
||||
// Create and set up the window.
|
||||
frame = new JFrame("Shi-Tomasi corner detector 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("Max corners:"));
|
||||
JSlider slider = new JSlider(0, MAX_THRESHOLD, maxCorners);
|
||||
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();
|
||||
maxCorners = source.getValue();
|
||||
update();
|
||||
}
|
||||
});
|
||||
sliderPanel.add(slider);
|
||||
pane.add(sliderPanel, BorderLayout.PAGE_START);
|
||||
|
||||
imgLabel = new JLabel(new ImageIcon(img));
|
||||
pane.add(imgLabel, BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
private void update() {
|
||||
/// Parameters for Shi-Tomasi algorithm
|
||||
maxCorners = Math.max(maxCorners, 1);
|
||||
MatOfPoint corners = new MatOfPoint();
|
||||
double qualityLevel = 0.01;
|
||||
double minDistance = 10;
|
||||
int blockSize = 3, gradientSize = 3;
|
||||
boolean useHarrisDetector = false;
|
||||
double k = 0.04;
|
||||
|
||||
/// Copy the source image
|
||||
Mat copy = src.clone();
|
||||
|
||||
/// Apply corner detection
|
||||
Imgproc.goodFeaturesToTrack(srcGray, corners, maxCorners, qualityLevel, minDistance, new Mat(),
|
||||
blockSize, gradientSize, useHarrisDetector, k);
|
||||
|
||||
/// Draw corners detected
|
||||
System.out.println("** Number of corners detected: " + corners.rows());
|
||||
int[] cornersData = new int[(int) (corners.total() * corners.channels())];
|
||||
corners.get(0, 0, cornersData);
|
||||
int radius = 4;
|
||||
for (int i = 0; i < corners.rows(); i++) {
|
||||
Imgproc.circle(copy, new Point(cornersData[i * 2], cornersData[i * 2 + 1]), radius,
|
||||
new Scalar(rng.nextInt(256), rng.nextInt(256), rng.nextInt(256)), Core.FILLED);
|
||||
}
|
||||
|
||||
imgLabel.setIcon(new ImageIcon(HighGui.toBufferedImage(copy)));
|
||||
frame.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
public class GoodFeaturesToTrackDemo {
|
||||
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 GoodFeaturesToTrack(args);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Container;
|
||||
import java.awt.Image;
|
||||
|
||||
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.Point;
|
||||
import org.opencv.core.Scalar;
|
||||
import org.opencv.highgui.HighGui;
|
||||
import org.opencv.imgcodecs.Imgcodecs;
|
||||
import org.opencv.imgproc.Imgproc;
|
||||
|
||||
class CornerHarris {
|
||||
private Mat srcGray = new Mat();
|
||||
private Mat dst = new Mat();
|
||||
private Mat dstNorm = new Mat();
|
||||
private Mat dstNormScaled = new Mat();
|
||||
private JFrame frame;
|
||||
private JLabel imgLabel;
|
||||
private JLabel cornerLabel;
|
||||
private static final int MAX_THRESHOLD = 255;
|
||||
private int threshold = 200;
|
||||
|
||||
public CornerHarris(String[] args) {
|
||||
/// Load source image and convert it to gray
|
||||
String filename = args.length > 0 ? args[0] : "../data/building.jpg";
|
||||
Mat src = Imgcodecs.imread(filename);
|
||||
if (src.empty()) {
|
||||
System.err.println("Cannot read image: " + filename);
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
Imgproc.cvtColor(src, srcGray, Imgproc.COLOR_BGR2GRAY);
|
||||
|
||||
// Create and set up the window.
|
||||
frame = new JFrame("Harris corner detector 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("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();
|
||||
imgLabel = new JLabel(new ImageIcon(img));
|
||||
imgPanel.add(imgLabel);
|
||||
|
||||
Mat blackImg = Mat.zeros(srcGray.size(), CvType.CV_8U);
|
||||
cornerLabel = new JLabel(new ImageIcon(HighGui.toBufferedImage(blackImg)));
|
||||
imgPanel.add(cornerLabel);
|
||||
|
||||
pane.add(imgPanel, BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
private void update() {
|
||||
dst = Mat.zeros(srcGray.size(), CvType.CV_32F);
|
||||
|
||||
/// Detector parameters
|
||||
int blockSize = 2;
|
||||
int apertureSize = 3;
|
||||
double k = 0.04;
|
||||
|
||||
/// Detecting corners
|
||||
Imgproc.cornerHarris(srcGray, dst, blockSize, apertureSize, k);
|
||||
|
||||
/// Normalizing
|
||||
Core.normalize(dst, dstNorm, 0, 255, Core.NORM_MINMAX);
|
||||
Core.convertScaleAbs(dstNorm, dstNormScaled);
|
||||
|
||||
/// Drawing a circle around corners
|
||||
float[] dstNormData = new float[(int) (dstNorm.total() * dstNorm.channels())];
|
||||
dstNorm.get(0, 0, dstNormData);
|
||||
|
||||
for (int i = 0; i < dstNorm.rows(); i++) {
|
||||
for (int j = 0; j < dstNorm.cols(); j++) {
|
||||
if ((int) dstNormData[i * dstNorm.cols() + j] > threshold) {
|
||||
Imgproc.circle(dstNormScaled, new Point(j, i), 5, new Scalar(0), 2, 8, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cornerLabel.setIcon(new ImageIcon(HighGui.toBufferedImage(dstNormScaled)));
|
||||
frame.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
public class CornerHarrisDemo {
|
||||
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 CornerHarris(args);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
import org.opencv.core.Core;
|
||||
import org.opencv.core.Mat;
|
||||
import org.opencv.core.MatOfDMatch;
|
||||
import org.opencv.core.MatOfKeyPoint;
|
||||
import org.opencv.features2d.DescriptorMatcher;
|
||||
import org.opencv.features2d.Features2d;
|
||||
import org.opencv.highgui.HighGui;
|
||||
import org.opencv.imgcodecs.Imgcodecs;
|
||||
import org.opencv.xfeatures2d.SURF;
|
||||
|
||||
class SURFMatching {
|
||||
public void run(String[] args) {
|
||||
String filename1 = args.length > 1 ? args[0] : "../data/box.png";
|
||||
String filename2 = args.length > 1 ? args[1] : "../data/box_in_scene.png";
|
||||
Mat img1 = Imgcodecs.imread(filename1, Imgcodecs.IMREAD_GRAYSCALE);
|
||||
Mat img2 = Imgcodecs.imread(filename2, Imgcodecs.IMREAD_GRAYSCALE);
|
||||
if (img1.empty() || img2.empty()) {
|
||||
System.err.println("Cannot read images!");
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
//-- Step 1: Detect the keypoints using SURF Detector, compute the descriptors
|
||||
double hessianThreshold = 400;
|
||||
int nOctaves = 4, nOctaveLayers = 3;
|
||||
boolean extended = false, upright = false;
|
||||
SURF detector = SURF.create(hessianThreshold, nOctaves, nOctaveLayers, extended, upright);
|
||||
MatOfKeyPoint keypoints1 = new MatOfKeyPoint(), keypoints2 = new MatOfKeyPoint();
|
||||
Mat descriptors1 = new Mat(), descriptors2 = new Mat();
|
||||
detector.detectAndCompute(img1, new Mat(), keypoints1, descriptors1);
|
||||
detector.detectAndCompute(img2, new Mat(), keypoints2, descriptors2);
|
||||
|
||||
//-- Step 2: Matching descriptor vectors with a brute force matcher
|
||||
// Since SURF is a floating-point descriptor NORM_L2 is used
|
||||
DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE);
|
||||
MatOfDMatch matches = new MatOfDMatch();
|
||||
matcher.match(descriptors1, descriptors2, matches);
|
||||
|
||||
//-- Draw matches
|
||||
Mat imgMatches = new Mat();
|
||||
Features2d.drawMatches(img1, keypoints1, img2, keypoints2, matches, imgMatches);
|
||||
|
||||
HighGui.imshow("Matches", imgMatches);
|
||||
HighGui.waitKey(0);
|
||||
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
public class SURFMatchingDemo {
|
||||
public static void main(String[] args) {
|
||||
// Load the native OpenCV library
|
||||
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
|
||||
|
||||
new SURFMatching().run(args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
import org.opencv.core.Core;
|
||||
import org.opencv.core.Mat;
|
||||
import org.opencv.core.MatOfKeyPoint;
|
||||
import org.opencv.features2d.Features2d;
|
||||
import org.opencv.highgui.HighGui;
|
||||
import org.opencv.imgcodecs.Imgcodecs;
|
||||
import org.opencv.xfeatures2d.SURF;
|
||||
|
||||
class SURFDetection {
|
||||
public void run(String[] args) {
|
||||
String filename = args.length > 0 ? args[0] : "../data/box.png";
|
||||
Mat src = Imgcodecs.imread(filename, Imgcodecs.IMREAD_GRAYSCALE);
|
||||
if (src.empty()) {
|
||||
System.err.println("Cannot read image: " + filename);
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
//-- Step 1: Detect the keypoints using SURF Detector
|
||||
double hessianThreshold = 400;
|
||||
int nOctaves = 4, nOctaveLayers = 3;
|
||||
boolean extended = false, upright = false;
|
||||
SURF detector = SURF.create(hessianThreshold, nOctaves, nOctaveLayers, extended, upright);
|
||||
MatOfKeyPoint keypoints = new MatOfKeyPoint();
|
||||
detector.detect(src, keypoints);
|
||||
|
||||
//-- Draw keypoints
|
||||
Features2d.drawKeypoints(src, keypoints, src);
|
||||
|
||||
//-- Show detected (drawn) keypoints
|
||||
HighGui.imshow("SURF Keypoints", src);
|
||||
HighGui.waitKey(0);
|
||||
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
public class SURFDetectionDemo {
|
||||
public static void main(String[] args) {
|
||||
// Load the native OpenCV library
|
||||
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
|
||||
|
||||
new SURFDetection().run(args);
|
||||
}
|
||||
}
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.opencv.core.Core;
|
||||
import org.opencv.core.DMatch;
|
||||
import org.opencv.core.Mat;
|
||||
import org.opencv.core.MatOfByte;
|
||||
import org.opencv.core.MatOfDMatch;
|
||||
import org.opencv.core.MatOfKeyPoint;
|
||||
import org.opencv.core.Scalar;
|
||||
import org.opencv.features2d.DescriptorMatcher;
|
||||
import org.opencv.features2d.Features2d;
|
||||
import org.opencv.highgui.HighGui;
|
||||
import org.opencv.imgcodecs.Imgcodecs;
|
||||
import org.opencv.xfeatures2d.SURF;
|
||||
|
||||
class SURFFLANNMatching {
|
||||
public void run(String[] args) {
|
||||
String filename1 = args.length > 1 ? args[0] : "../data/box.png";
|
||||
String filename2 = args.length > 1 ? args[1] : "../data/box_in_scene.png";
|
||||
Mat img1 = Imgcodecs.imread(filename1, Imgcodecs.IMREAD_GRAYSCALE);
|
||||
Mat img2 = Imgcodecs.imread(filename2, Imgcodecs.IMREAD_GRAYSCALE);
|
||||
if (img1.empty() || img2.empty()) {
|
||||
System.err.println("Cannot read images!");
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
//-- Step 1: Detect the keypoints using SURF Detector, compute the descriptors
|
||||
double hessianThreshold = 400;
|
||||
int nOctaves = 4, nOctaveLayers = 3;
|
||||
boolean extended = false, upright = false;
|
||||
SURF detector = SURF.create(hessianThreshold, nOctaves, nOctaveLayers, extended, upright);
|
||||
MatOfKeyPoint keypoints1 = new MatOfKeyPoint(), keypoints2 = new MatOfKeyPoint();
|
||||
Mat descriptors1 = new Mat(), descriptors2 = new Mat();
|
||||
detector.detectAndCompute(img1, new Mat(), keypoints1, descriptors1);
|
||||
detector.detectAndCompute(img2, new Mat(), keypoints2, descriptors2);
|
||||
|
||||
//-- Step 2: Matching descriptor vectors with a FLANN based matcher
|
||||
// Since SURF is a floating-point descriptor NORM_L2 is used
|
||||
DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.FLANNBASED);
|
||||
List<MatOfDMatch> knnMatches = new ArrayList<>();
|
||||
matcher.knnMatch(descriptors1, descriptors2, knnMatches, 2);
|
||||
|
||||
//-- Filter matches using the Lowe's ratio test
|
||||
float ratio_thresh = 0.7f;
|
||||
List<DMatch> listOfGoodMatches = new ArrayList<>();
|
||||
for (int i = 0; i < knnMatches.size(); i++) {
|
||||
if (knnMatches.get(i).rows() > 1) {
|
||||
DMatch[] matches = knnMatches.get(i).toArray();
|
||||
if (matches[0].distance / matches[1].distance <= ratio_thresh) {
|
||||
listOfGoodMatches.add(matches[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
MatOfDMatch goodMatches = new MatOfDMatch();
|
||||
goodMatches.fromList(listOfGoodMatches);
|
||||
|
||||
//-- Draw matches
|
||||
Mat imgMatches = new Mat();
|
||||
Features2d.drawMatches(img1, keypoints1, img2, keypoints2, goodMatches, imgMatches, Scalar.all(-1),
|
||||
Scalar.all(-1), new MatOfByte(), Features2d.NOT_DRAW_SINGLE_POINTS);
|
||||
|
||||
//-- Show detected matches
|
||||
HighGui.imshow("Good Matches", imgMatches);
|
||||
HighGui.waitKey(0);
|
||||
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
public class SURFFLANNMatchingDemo {
|
||||
public static void main(String[] args) {
|
||||
// Load the native OpenCV library
|
||||
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
|
||||
|
||||
new SURFFLANNMatching().run(args);
|
||||
}
|
||||
}
|
||||
+130
@@ -0,0 +1,130 @@
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.opencv.calib3d.Calib3d;
|
||||
import org.opencv.core.Core;
|
||||
import org.opencv.core.CvType;
|
||||
import org.opencv.core.DMatch;
|
||||
import org.opencv.core.KeyPoint;
|
||||
import org.opencv.core.Mat;
|
||||
import org.opencv.core.MatOfByte;
|
||||
import org.opencv.core.MatOfDMatch;
|
||||
import org.opencv.core.MatOfKeyPoint;
|
||||
import org.opencv.core.MatOfPoint2f;
|
||||
import org.opencv.core.Point;
|
||||
import org.opencv.core.Scalar;
|
||||
import org.opencv.features2d.DescriptorMatcher;
|
||||
import org.opencv.features2d.Features2d;
|
||||
import org.opencv.highgui.HighGui;
|
||||
import org.opencv.imgcodecs.Imgcodecs;
|
||||
import org.opencv.imgproc.Imgproc;
|
||||
import org.opencv.xfeatures2d.SURF;
|
||||
|
||||
class SURFFLANNMatchingHomography {
|
||||
public void run(String[] args) {
|
||||
String filenameObject = args.length > 1 ? args[0] : "../data/box.png";
|
||||
String filenameScene = args.length > 1 ? args[1] : "../data/box_in_scene.png";
|
||||
Mat imgObject = Imgcodecs.imread(filenameObject, Imgcodecs.IMREAD_GRAYSCALE);
|
||||
Mat imgScene = Imgcodecs.imread(filenameScene, Imgcodecs.IMREAD_GRAYSCALE);
|
||||
if (imgObject.empty() || imgScene.empty()) {
|
||||
System.err.println("Cannot read images!");
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
//-- Step 1: Detect the keypoints using SURF Detector, compute the descriptors
|
||||
double hessianThreshold = 400;
|
||||
int nOctaves = 4, nOctaveLayers = 3;
|
||||
boolean extended = false, upright = false;
|
||||
SURF detector = SURF.create(hessianThreshold, nOctaves, nOctaveLayers, extended, upright);
|
||||
MatOfKeyPoint keypointsObject = new MatOfKeyPoint(), keypointsScene = new MatOfKeyPoint();
|
||||
Mat descriptorsObject = new Mat(), descriptorsScene = new Mat();
|
||||
detector.detectAndCompute(imgObject, new Mat(), keypointsObject, descriptorsObject);
|
||||
detector.detectAndCompute(imgScene, new Mat(), keypointsScene, descriptorsScene);
|
||||
|
||||
//-- Step 2: Matching descriptor vectors with a FLANN based matcher
|
||||
// Since SURF is a floating-point descriptor NORM_L2 is used
|
||||
DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.FLANNBASED);
|
||||
List<MatOfDMatch> knnMatches = new ArrayList<>();
|
||||
matcher.knnMatch(descriptorsObject, descriptorsScene, knnMatches, 2);
|
||||
|
||||
//-- Filter matches using the Lowe's ratio test
|
||||
float ratio_thresh = 0.75f;
|
||||
List<DMatch> listOfGoodMatches = new ArrayList<>();
|
||||
for (int i = 0; i < knnMatches.size(); i++) {
|
||||
if (knnMatches.get(i).rows() > 1) {
|
||||
DMatch[] matches = knnMatches.get(i).toArray();
|
||||
if (matches[0].distance / matches[1].distance <= ratio_thresh) {
|
||||
listOfGoodMatches.add(matches[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
MatOfDMatch goodMatches = new MatOfDMatch();
|
||||
goodMatches.fromList(listOfGoodMatches);
|
||||
|
||||
//-- Draw matches
|
||||
Mat imgMatches = new Mat();
|
||||
Features2d.drawMatches(imgObject, keypointsObject, imgScene, keypointsScene, goodMatches, imgMatches, Scalar.all(-1),
|
||||
Scalar.all(-1), new MatOfByte(), Features2d.NOT_DRAW_SINGLE_POINTS);
|
||||
|
||||
//-- Localize the object
|
||||
List<Point> obj = new ArrayList<>();
|
||||
List<Point> scene = new ArrayList<>();
|
||||
|
||||
List<KeyPoint> listOfKeypointsObject = keypointsObject.toList();
|
||||
List<KeyPoint> listOfKeypointsScene = keypointsScene.toList();
|
||||
for (int i = 0; i < listOfGoodMatches.size(); i++) {
|
||||
//-- Get the keypoints from the good matches
|
||||
obj.add(listOfKeypointsObject.get(listOfGoodMatches.get(i).queryIdx).pt);
|
||||
scene.add(listOfKeypointsScene.get(listOfGoodMatches.get(i).trainIdx).pt);
|
||||
}
|
||||
|
||||
MatOfPoint2f objMat = new MatOfPoint2f(), sceneMat = new MatOfPoint2f();
|
||||
objMat.fromList(obj);
|
||||
sceneMat.fromList(scene);
|
||||
double ransacReprojThreshold = 3.0;
|
||||
Mat H = Calib3d.findHomography( objMat, sceneMat, Calib3d.RANSAC, ransacReprojThreshold );
|
||||
|
||||
//-- Get the corners from the image_1 ( the object to be "detected" )
|
||||
Mat objCorners = new Mat(4, 1, CvType.CV_32FC2), sceneCorners = new Mat();
|
||||
float[] objCornersData = new float[(int) (objCorners.total() * objCorners.channels())];
|
||||
objCorners.get(0, 0, objCornersData);
|
||||
objCornersData[0] = 0;
|
||||
objCornersData[1] = 0;
|
||||
objCornersData[2] = imgObject.cols();
|
||||
objCornersData[3] = 0;
|
||||
objCornersData[4] = imgObject.cols();
|
||||
objCornersData[5] = imgObject.rows();
|
||||
objCornersData[6] = 0;
|
||||
objCornersData[7] = imgObject.rows();
|
||||
objCorners.put(0, 0, objCornersData);
|
||||
|
||||
Core.perspectiveTransform(objCorners, sceneCorners, H);
|
||||
float[] sceneCornersData = new float[(int) (sceneCorners.total() * sceneCorners.channels())];
|
||||
sceneCorners.get(0, 0, sceneCornersData);
|
||||
|
||||
//-- Draw lines between the corners (the mapped object in the scene - image_2 )
|
||||
Imgproc.line(imgMatches, new Point(sceneCornersData[0] + imgObject.cols(), sceneCornersData[1]),
|
||||
new Point(sceneCornersData[2] + imgObject.cols(), sceneCornersData[3]), new Scalar(0, 255, 0), 4);
|
||||
Imgproc.line(imgMatches, new Point(sceneCornersData[2] + imgObject.cols(), sceneCornersData[3]),
|
||||
new Point(sceneCornersData[4] + imgObject.cols(), sceneCornersData[5]), new Scalar(0, 255, 0), 4);
|
||||
Imgproc.line(imgMatches, new Point(sceneCornersData[4] + imgObject.cols(), sceneCornersData[5]),
|
||||
new Point(sceneCornersData[6] + imgObject.cols(), sceneCornersData[7]), new Scalar(0, 255, 0), 4);
|
||||
Imgproc.line(imgMatches, new Point(sceneCornersData[6] + imgObject.cols(), sceneCornersData[7]),
|
||||
new Point(sceneCornersData[0] + imgObject.cols(), sceneCornersData[1]), new Scalar(0, 255, 0), 4);
|
||||
|
||||
//-- Show detected matches
|
||||
HighGui.imshow("Good Matches & Object detection", imgMatches);
|
||||
HighGui.waitKey(0);
|
||||
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
public class SURFFLANNMatchingHomographyDemo {
|
||||
public static void main(String[] args) {
|
||||
// Load the native OpenCV library
|
||||
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
|
||||
|
||||
new SURFFLANNMatchingHomography().run(args);
|
||||
}
|
||||
}
|
||||
@@ -71,7 +71,7 @@ if __name__ == '__main__':
|
||||
if debug_dir:
|
||||
vis = cv.cvtColor(img, cv.COLOR_GRAY2BGR)
|
||||
cv.drawChessboardCorners(vis, pattern_size, corners, found)
|
||||
path, name, ext = splitfn(fn)
|
||||
_path, name, _ext = splitfn(fn)
|
||||
outfile = os.path.join(debug_dir, name + '_chess.png')
|
||||
cv.imwrite(outfile, vis)
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@ def create_board_model(extrinsics, board_width, board_height, square_size, draw_
|
||||
|
||||
# draw calibration board
|
||||
X_board = np.ones((4,5))
|
||||
X_board_cam = np.ones((extrinsics.shape[0],4,5))
|
||||
#X_board_cam = np.ones((extrinsics.shape[0],4,5))
|
||||
X_board[0:3,0] = [0,0,0]
|
||||
X_board[0:3,1] = [width,0,0]
|
||||
X_board[0:3,2] = [width,height,0]
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ src = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
|
||||
## [Convert to grayscale]
|
||||
|
||||
## [Apply Histogram Equalization]
|
||||
dst = cv.equalizeHist(src);
|
||||
dst = cv.equalizeHist(src)
|
||||
## [Apply Histogram Equalization]
|
||||
|
||||
## [Display results]
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
from __future__ import print_function
|
||||
import cv2 as cv
|
||||
import numpy as np
|
||||
import argparse
|
||||
import random as rng
|
||||
|
||||
source_window = 'Image'
|
||||
maxTrackbar = 25
|
||||
rng.seed(12345)
|
||||
|
||||
def goodFeaturesToTrack_Demo(val):
|
||||
maxCorners = max(val, 1)
|
||||
|
||||
# Parameters for Shi-Tomasi algorithm
|
||||
qualityLevel = 0.01
|
||||
minDistance = 10
|
||||
blockSize = 3
|
||||
gradientSize = 3
|
||||
useHarrisDetector = False
|
||||
k = 0.04
|
||||
|
||||
# Copy the source image
|
||||
copy = np.copy(src)
|
||||
|
||||
# Apply corner detection
|
||||
corners = cv.goodFeaturesToTrack(src_gray, maxCorners, qualityLevel, minDistance, None, \
|
||||
blockSize=blockSize, gradientSize=gradientSize, useHarrisDetector=useHarrisDetector, k=k)
|
||||
|
||||
# Draw corners detected
|
||||
print('** Number of corners detected:', corners.shape[0])
|
||||
radius = 4
|
||||
for i in range(corners.shape[0]):
|
||||
cv.circle(copy, (corners[i,0,0], corners[i,0,1]), radius, (rng.randint(0,256), rng.randint(0,256), rng.randint(0,256)), cv.FILLED)
|
||||
|
||||
# Show what you got
|
||||
cv.namedWindow(source_window)
|
||||
cv.imshow(source_window, copy)
|
||||
|
||||
# Set the needed parameters to find the refined corners
|
||||
winSize = (5, 5)
|
||||
zeroZone = (-1, -1)
|
||||
criteria = (cv.TERM_CRITERIA_EPS + cv.TermCriteria_COUNT, 40, 0.001)
|
||||
|
||||
# Calculate the refined corner locations
|
||||
corners = cv.cornerSubPix(src_gray, corners, winSize, zeroZone, criteria)
|
||||
|
||||
# Write them down
|
||||
for i in range(corners.shape[0]):
|
||||
print(" -- Refined Corner [", i, "] (", corners[i,0,0], ",", corners[i,0,1], ")")
|
||||
|
||||
# Load source image and convert it to gray
|
||||
parser = argparse.ArgumentParser(description='Code for Shi-Tomasi corner detector tutorial.')
|
||||
parser.add_argument('--input', help='Path to input image.', default='../data/pic3.png')
|
||||
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)
|
||||
|
||||
src_gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
|
||||
|
||||
# Create a window and a trackbar
|
||||
cv.namedWindow(source_window)
|
||||
maxCorners = 10 # initial threshold
|
||||
cv.createTrackbar('Threshold: ', source_window, maxCorners, maxTrackbar, goodFeaturesToTrack_Demo)
|
||||
cv.imshow(source_window, src)
|
||||
goodFeaturesToTrack_Demo(maxCorners)
|
||||
|
||||
cv.waitKey()
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
from __future__ import print_function
|
||||
import cv2 as cv
|
||||
import numpy as np
|
||||
import argparse
|
||||
import random as rng
|
||||
|
||||
myHarris_window = 'My Harris corner detector'
|
||||
myShiTomasi_window = 'My Shi Tomasi corner detector'
|
||||
myHarris_qualityLevel = 50
|
||||
myShiTomasi_qualityLevel = 50
|
||||
max_qualityLevel = 100
|
||||
rng.seed(12345)
|
||||
|
||||
def myHarris_function(val):
|
||||
myHarris_copy = np.copy(src)
|
||||
myHarris_qualityLevel = max(val, 1)
|
||||
|
||||
for i in range(src_gray.shape[0]):
|
||||
for j in range(src_gray.shape[1]):
|
||||
if Mc[i,j] > myHarris_minVal + ( myHarris_maxVal - myHarris_minVal )*myHarris_qualityLevel/max_qualityLevel:
|
||||
cv.circle(myHarris_copy, (j,i), 4, (rng.randint(0,256), rng.randint(0,256), rng.randint(0,256)), cv.FILLED)
|
||||
|
||||
cv.imshow(myHarris_window, myHarris_copy)
|
||||
|
||||
def myShiTomasi_function(val):
|
||||
myShiTomasi_copy = np.copy(src)
|
||||
myShiTomasi_qualityLevel = max(val, 1)
|
||||
|
||||
for i in range(src_gray.shape[0]):
|
||||
for j in range(src_gray.shape[1]):
|
||||
if myShiTomasi_dst[i,j] > myShiTomasi_minVal + ( myShiTomasi_maxVal - myShiTomasi_minVal )*myShiTomasi_qualityLevel/max_qualityLevel:
|
||||
cv.circle(myShiTomasi_copy, (j,i), 4, (rng.randint(0,256), rng.randint(0,256), rng.randint(0,256)), cv.FILLED)
|
||||
|
||||
cv.imshow(myShiTomasi_window, myShiTomasi_copy)
|
||||
|
||||
# Load source image and convert it to gray
|
||||
parser = argparse.ArgumentParser(description='Code for Creating your own corner detector tutorial.')
|
||||
parser.add_argument('--input', help='Path to input image.', default='../data/building.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)
|
||||
|
||||
src_gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
|
||||
|
||||
# Set some parameters
|
||||
blockSize = 3
|
||||
apertureSize = 3
|
||||
|
||||
# My Harris matrix -- Using cornerEigenValsAndVecs
|
||||
myHarris_dst = cv.cornerEigenValsAndVecs(src_gray, blockSize, apertureSize)
|
||||
|
||||
# calculate Mc
|
||||
Mc = np.empty(src_gray.shape, dtype=np.float32)
|
||||
for i in range(src_gray.shape[0]):
|
||||
for j in range(src_gray.shape[1]):
|
||||
lambda_1 = myHarris_dst[i,j,0]
|
||||
lambda_2 = myHarris_dst[i,j,1]
|
||||
Mc[i,j] = lambda_1*lambda_2 - 0.04*pow( ( lambda_1 + lambda_2 ), 2 )
|
||||
|
||||
myHarris_minVal, myHarris_maxVal, _, _ = cv.minMaxLoc(Mc)
|
||||
|
||||
# Create Window and Trackbar
|
||||
cv.namedWindow(myHarris_window)
|
||||
cv.createTrackbar('Quality Level:', myHarris_window, myHarris_qualityLevel, max_qualityLevel, myHarris_function)
|
||||
myHarris_function(myHarris_qualityLevel)
|
||||
|
||||
# My Shi-Tomasi -- Using cornerMinEigenVal
|
||||
myShiTomasi_dst = cv.cornerMinEigenVal(src_gray, blockSize, apertureSize)
|
||||
|
||||
myShiTomasi_minVal, myShiTomasi_maxVal, _, _ = cv.minMaxLoc(myShiTomasi_dst)
|
||||
|
||||
# Create Window and Trackbar
|
||||
cv.namedWindow(myShiTomasi_window)
|
||||
cv.createTrackbar('Quality Level:', myShiTomasi_window, myShiTomasi_qualityLevel, max_qualityLevel, myShiTomasi_function)
|
||||
myShiTomasi_function(myShiTomasi_qualityLevel)
|
||||
|
||||
cv.waitKey()
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
from __future__ import print_function
|
||||
import cv2 as cv
|
||||
import numpy as np
|
||||
import argparse
|
||||
import random as rng
|
||||
|
||||
source_window = 'Image'
|
||||
maxTrackbar = 100
|
||||
rng.seed(12345)
|
||||
|
||||
def goodFeaturesToTrack_Demo(val):
|
||||
maxCorners = max(val, 1)
|
||||
|
||||
# Parameters for Shi-Tomasi algorithm
|
||||
qualityLevel = 0.01
|
||||
minDistance = 10
|
||||
blockSize = 3
|
||||
gradientSize = 3
|
||||
useHarrisDetector = False
|
||||
k = 0.04
|
||||
|
||||
# Copy the source image
|
||||
copy = np.copy(src)
|
||||
|
||||
# Apply corner detection
|
||||
corners = cv.goodFeaturesToTrack(src_gray, maxCorners, qualityLevel, minDistance, None, \
|
||||
blockSize=blockSize, gradientSize=gradientSize, useHarrisDetector=useHarrisDetector, k=k)
|
||||
|
||||
# Draw corners detected
|
||||
print('** Number of corners detected:', corners.shape[0])
|
||||
radius = 4
|
||||
for i in range(corners.shape[0]):
|
||||
cv.circle(copy, (corners[i,0,0], corners[i,0,1]), radius, (rng.randint(0,256), rng.randint(0,256), rng.randint(0,256)), cv.FILLED)
|
||||
|
||||
# Show what you got
|
||||
cv.namedWindow(source_window)
|
||||
cv.imshow(source_window, copy)
|
||||
|
||||
# Load source image and convert it to gray
|
||||
parser = argparse.ArgumentParser(description='Code for Shi-Tomasi corner detector tutorial.')
|
||||
parser.add_argument('--input', help='Path to input image.', default='../data/pic3.png')
|
||||
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)
|
||||
|
||||
src_gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
|
||||
|
||||
# Create a window and a trackbar
|
||||
cv.namedWindow(source_window)
|
||||
maxCorners = 23 # initial threshold
|
||||
cv.createTrackbar('Threshold: ', source_window, maxCorners, maxTrackbar, goodFeaturesToTrack_Demo)
|
||||
cv.imshow(source_window, src)
|
||||
goodFeaturesToTrack_Demo(maxCorners)
|
||||
|
||||
cv.waitKey()
|
||||
@@ -0,0 +1,55 @@
|
||||
from __future__ import print_function
|
||||
import cv2 as cv
|
||||
import numpy as np
|
||||
import argparse
|
||||
|
||||
source_window = 'Source image'
|
||||
corners_window = 'Corners detected'
|
||||
max_thresh = 255
|
||||
|
||||
def cornerHarris_demo(val):
|
||||
thresh = val
|
||||
|
||||
# Detector parameters
|
||||
blockSize = 2
|
||||
apertureSize = 3
|
||||
k = 0.04
|
||||
|
||||
# Detecting corners
|
||||
dst = cv.cornerHarris(src_gray, blockSize, apertureSize, k)
|
||||
|
||||
# Normalizing
|
||||
dst_norm = np.empty(dst.shape, dtype=np.float32)
|
||||
cv.normalize(dst, dst_norm, alpha=0, beta=255, norm_type=cv.NORM_MINMAX)
|
||||
dst_norm_scaled = cv.convertScaleAbs(dst_norm)
|
||||
|
||||
# Drawing a circle around corners
|
||||
for i in range(dst_norm.shape[0]):
|
||||
for j in range(dst_norm.shape[1]):
|
||||
if int(dst_norm[i,j]) > thresh:
|
||||
cv.circle(dst_norm_scaled, (j,i), 5, (0), 2)
|
||||
|
||||
# Showing the result
|
||||
cv.namedWindow(corners_window)
|
||||
cv.imshow(corners_window, dst_norm_scaled)
|
||||
|
||||
# Load source image and convert it to gray
|
||||
parser = argparse.ArgumentParser(description='Code for Harris corner detector tutorial.')
|
||||
parser.add_argument('--input', help='Path to input image.', default='../data/building.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)
|
||||
|
||||
src_gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
|
||||
|
||||
# Create a window and a trackbar
|
||||
cv.namedWindow(source_window)
|
||||
thresh = 200 # initial threshold
|
||||
cv.createTrackbar('Threshold: ', source_window, thresh, max_thresh, cornerHarris_demo)
|
||||
cv.imshow(source_window, src)
|
||||
cornerHarris_demo(thresh)
|
||||
|
||||
cv.waitKey()
|
||||
@@ -0,0 +1,35 @@
|
||||
from __future__ import print_function
|
||||
import cv2 as cv
|
||||
import numpy as np
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(description='Code for Feature Detection tutorial.')
|
||||
parser.add_argument('--input1', help='Path to input image 1.', default='../data/box.png')
|
||||
parser.add_argument('--input2', help='Path to input image 2.', default='../data/box_in_scene.png')
|
||||
args = parser.parse_args()
|
||||
|
||||
img1 = cv.imread(args.input1, cv.IMREAD_GRAYSCALE)
|
||||
img2 = cv.imread(args.input2, cv.IMREAD_GRAYSCALE)
|
||||
if img1 is None or img2 is None:
|
||||
print('Could not open or find the images!')
|
||||
exit(0)
|
||||
|
||||
#-- Step 1: Detect the keypoints using SURF Detector, compute the descriptors
|
||||
minHessian = 400
|
||||
detector = cv.xfeatures2d_SURF.create(hessianThreshold=minHessian)
|
||||
keypoints1, descriptors1 = detector.detectAndCompute(img1, None)
|
||||
keypoints2, descriptors2 = detector.detectAndCompute(img2, None)
|
||||
|
||||
#-- Step 2: Matching descriptor vectors with a brute force matcher
|
||||
# Since SURF is a floating-point descriptor NORM_L2 is used
|
||||
matcher = cv.DescriptorMatcher_create(cv.DescriptorMatcher_BRUTEFORCE)
|
||||
matches = matcher.match(descriptors1, descriptors2)
|
||||
|
||||
#-- Draw matches
|
||||
img_matches = np.empty((max(img1.shape[0], img2.shape[0]), img1.shape[1]+img2.shape[1], 3), dtype=np.uint8)
|
||||
cv.drawMatches(img1, keypoints1, img2, keypoints2, matches, img_matches)
|
||||
|
||||
#-- Show detected matches
|
||||
cv.imshow('Matches', img_matches)
|
||||
|
||||
cv.waitKey()
|
||||
@@ -0,0 +1,27 @@
|
||||
from __future__ import print_function
|
||||
import cv2 as cv
|
||||
import numpy as np
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(description='Code for Feature Detection tutorial.')
|
||||
parser.add_argument('--input', help='Path to input image.', default='../data/box.png')
|
||||
args = parser.parse_args()
|
||||
|
||||
src = cv.imread(args.input, cv.IMREAD_GRAYSCALE)
|
||||
if src is None:
|
||||
print('Could not open or find the image:', args.input)
|
||||
exit(0)
|
||||
|
||||
#-- Step 1: Detect the keypoints using SURF Detector
|
||||
minHessian = 400
|
||||
detector = cv.xfeatures2d_SURF.create(hessianThreshold=minHessian)
|
||||
keypoints = detector.detect(src)
|
||||
|
||||
#-- Draw keypoints
|
||||
img_keypoints = np.empty((src.shape[0], src.shape[1], 3), dtype=np.uint8)
|
||||
cv.drawKeypoints(src, keypoints, img_keypoints)
|
||||
|
||||
#-- Show detected (drawn) keypoints
|
||||
cv.imshow('SURF Keypoints', img_keypoints)
|
||||
|
||||
cv.waitKey()
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
from __future__ import print_function
|
||||
import cv2 as cv
|
||||
import numpy as np
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(description='Code for Feature Matching with FLANN tutorial.')
|
||||
parser.add_argument('--input1', help='Path to input image 1.', default='../data/box.png')
|
||||
parser.add_argument('--input2', help='Path to input image 2.', default='../data/box_in_scene.png')
|
||||
args = parser.parse_args()
|
||||
|
||||
img1 = cv.imread(args.input1, cv.IMREAD_GRAYSCALE)
|
||||
img2 = cv.imread(args.input2, cv.IMREAD_GRAYSCALE)
|
||||
if img1 is None or img2 is None:
|
||||
print('Could not open or find the images!')
|
||||
exit(0)
|
||||
|
||||
#-- Step 1: Detect the keypoints using SURF Detector, compute the descriptors
|
||||
minHessian = 400
|
||||
detector = cv.xfeatures2d_SURF.create(hessianThreshold=minHessian)
|
||||
keypoints1, descriptors1 = detector.detectAndCompute(img1, None)
|
||||
keypoints2, descriptors2 = detector.detectAndCompute(img2, None)
|
||||
|
||||
#-- Step 2: Matching descriptor vectors with a FLANN based matcher
|
||||
# Since SURF is a floating-point descriptor NORM_L2 is used
|
||||
matcher = cv.DescriptorMatcher_create(cv.DescriptorMatcher_FLANNBASED)
|
||||
knn_matches = matcher.knnMatch(descriptors1, descriptors2, 2)
|
||||
|
||||
#-- Filter matches using the Lowe's ratio test
|
||||
ratio_thresh = 0.7
|
||||
good_matches = []
|
||||
for matches in knn_matches:
|
||||
if len(matches) > 1:
|
||||
if matches[0].distance / matches[1].distance <= ratio_thresh:
|
||||
good_matches.append(matches[0])
|
||||
|
||||
#-- Draw matches
|
||||
img_matches = np.empty((max(img1.shape[0], img2.shape[0]), img1.shape[1]+img2.shape[1], 3), dtype=np.uint8)
|
||||
cv.drawMatches(img1, keypoints1, img2, keypoints2, good_matches, img_matches, flags=cv.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)
|
||||
|
||||
#-- Show detected matches
|
||||
cv.imshow('Good Matches', img_matches)
|
||||
|
||||
cv.waitKey()
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
from __future__ import print_function
|
||||
import cv2 as cv
|
||||
import numpy as np
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(description='Code for Feature Matching with FLANN tutorial.')
|
||||
parser.add_argument('--input1', help='Path to input image 1.', default='../data/box.png')
|
||||
parser.add_argument('--input2', help='Path to input image 2.', default='../data/box_in_scene.png')
|
||||
args = parser.parse_args()
|
||||
|
||||
img_object = cv.imread(args.input1, cv.IMREAD_GRAYSCALE)
|
||||
img_scene = cv.imread(args.input2, cv.IMREAD_GRAYSCALE)
|
||||
if img_object is None or img_scene is None:
|
||||
print('Could not open or find the images!')
|
||||
exit(0)
|
||||
|
||||
#-- Step 1: Detect the keypoints using SURF Detector, compute the descriptors
|
||||
minHessian = 400
|
||||
detector = cv.xfeatures2d_SURF.create(hessianThreshold=minHessian)
|
||||
keypoints_obj, descriptors_obj = detector.detectAndCompute(img_object, None)
|
||||
keypoints_scene, descriptors_scene = detector.detectAndCompute(img_scene, None)
|
||||
|
||||
#-- Step 2: Matching descriptor vectors with a FLANN based matcher
|
||||
# Since SURF is a floating-point descriptor NORM_L2 is used
|
||||
matcher = cv.DescriptorMatcher_create(cv.DescriptorMatcher_FLANNBASED)
|
||||
knn_matches = matcher.knnMatch(descriptors_obj, descriptors_scene, 2)
|
||||
|
||||
#-- Filter matches using the Lowe's ratio test
|
||||
ratio_thresh = 0.75
|
||||
good_matches = []
|
||||
for matches in knn_matches:
|
||||
if len(matches) > 1:
|
||||
if matches[0].distance / matches[1].distance <= ratio_thresh:
|
||||
good_matches.append(matches[0])
|
||||
|
||||
#-- Draw matches
|
||||
img_matches = np.empty((max(img_object.shape[0], img_scene.shape[0]), img_object.shape[1]+img_scene.shape[1], 3), dtype=np.uint8)
|
||||
cv.drawMatches(img_object, keypoints_obj, img_scene, keypoints_scene, good_matches, img_matches, flags=cv.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)
|
||||
|
||||
#-- Localize the object
|
||||
obj = np.empty((len(good_matches),2), dtype=np.float32)
|
||||
scene = np.empty((len(good_matches),2), dtype=np.float32)
|
||||
for i in range(len(good_matches)):
|
||||
#-- Get the keypoints from the good matches
|
||||
obj[i,0] = keypoints_obj[good_matches[i].queryIdx].pt[0]
|
||||
obj[i,1] = keypoints_obj[good_matches[i].queryIdx].pt[1]
|
||||
scene[i,0] = keypoints_scene[good_matches[i].trainIdx].pt[0]
|
||||
scene[i,1] = keypoints_scene[good_matches[i].trainIdx].pt[1]
|
||||
|
||||
H, _ = cv.findHomography(obj, scene, cv.RANSAC)
|
||||
|
||||
#-- Get the corners from the image_1 ( the object to be "detected" )
|
||||
obj_corners = np.empty((4,1,2), dtype=np.float32)
|
||||
obj_corners[0,0,0] = 0
|
||||
obj_corners[0,0,1] = 0
|
||||
obj_corners[1,0,0] = img_object.shape[1]
|
||||
obj_corners[1,0,1] = 0
|
||||
obj_corners[2,0,0] = img_object.shape[1]
|
||||
obj_corners[2,0,1] = img_object.shape[0]
|
||||
obj_corners[3,0,0] = 0
|
||||
obj_corners[3,0,1] = img_object.shape[0]
|
||||
|
||||
scene_corners = cv.perspectiveTransform(obj_corners, H)
|
||||
|
||||
#-- Draw lines between the corners (the mapped object in the scene - image_2 )
|
||||
cv.line(img_matches, (int(scene_corners[0,0,0] + img_object.shape[1]), int(scene_corners[0,0,1])),\
|
||||
(int(scene_corners[1,0,0] + img_object.shape[1]), int(scene_corners[1,0,1])), (0,255,0), 4)
|
||||
cv.line(img_matches, (int(scene_corners[1,0,0] + img_object.shape[1]), int(scene_corners[1,0,1])),\
|
||||
(int(scene_corners[2,0,0] + img_object.shape[1]), int(scene_corners[2,0,1])), (0,255,0), 4)
|
||||
cv.line(img_matches, (int(scene_corners[2,0,0] + img_object.shape[1]), int(scene_corners[2,0,1])),\
|
||||
(int(scene_corners[3,0,0] + img_object.shape[1]), int(scene_corners[3,0,1])), (0,255,0), 4)
|
||||
cv.line(img_matches, (int(scene_corners[3,0,0] + img_object.shape[1]), int(scene_corners[3,0,1])),\
|
||||
(int(scene_corners[0,0,0] + img_object.shape[1]), int(scene_corners[0,0,1])), (0,255,0), 4)
|
||||
|
||||
#-- Show detected matches
|
||||
cv.imshow('Good Matches & Object detection', img_matches)
|
||||
|
||||
cv.waitKey()
|
||||
@@ -88,7 +88,7 @@ def main(argv):
|
||||
def display_caption(caption):
|
||||
global dst
|
||||
dst = np.zeros(src.shape, src.dtype)
|
||||
rows, cols, ch = src.shape
|
||||
rows, cols, _ch = src.shape
|
||||
cv.putText(dst, caption,
|
||||
(int(cols / 4), int(rows / 2)),
|
||||
cv.FONT_HERSHEY_COMPLEX, 1, (255, 255, 255))
|
||||
|
||||
@@ -33,7 +33,7 @@ if src is None:
|
||||
print('Could not open or find the image: ', args.input)
|
||||
exit(0)
|
||||
# Convert the image to Gray
|
||||
src_gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY);
|
||||
src_gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
|
||||
## [load]
|
||||
|
||||
## [window]
|
||||
|
||||
@@ -94,7 +94,7 @@ while True:
|
||||
break
|
||||
|
||||
frame_HSV = cv.cvtColor(frame, cv.COLOR_BGR2HSV)
|
||||
frame_threshold = cv.inRange(frame_HSV, (low_H, low_S, low_V), (high_H, high_S, high_V));
|
||||
frame_threshold = cv.inRange(frame_HSV, (low_H, low_S, low_V), (high_H, high_S, high_V))
|
||||
## [while]
|
||||
|
||||
## [show]
|
||||
|
||||
Reference in New Issue
Block a user