removed contrib, legacy and softcsscade modules; removed latentsvm and datamatrix detector from objdetect. removed haartraining and sft apps.
some of the stuff will be moved to opencv_contrib module. in order to make this PR pass buildbot, please, comment off opencv_legacy, opencv_contrib and opencv_softcascade test runs.
@@ -10,7 +10,6 @@ if(NOT CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_LIST_DIR)
|
||||
#
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
add_subdirectory(c)
|
||||
add_subdirectory(cpp)
|
||||
add_subdirectory(gpu)
|
||||
add_subdirectory(tapi)
|
||||
@@ -60,7 +59,6 @@ if(MSVC)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_subdirectory(c)
|
||||
add_subdirectory(cpp)
|
||||
# FIXIT: can't use cvconfig.h in samples: add_subdirectory(gpu)
|
||||
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
# ----------------------------------------------------------------------------
|
||||
# CMake file for C samples. See root CMakeLists.txt
|
||||
#
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
SET(OPENCV_C_SAMPLES_REQUIRED_DEPS opencv_core opencv_flann opencv_imgproc
|
||||
opencv_highgui opencv_ml opencv_video opencv_objdetect opencv_photo opencv_nonfree
|
||||
opencv_features2d opencv_calib3d opencv_legacy opencv_contrib)
|
||||
|
||||
ocv_check_dependencies(${OPENCV_C_SAMPLES_REQUIRED_DEPS})
|
||||
|
||||
if(BUILD_EXAMPLES AND OCV_DEPENDENCIES_FOUND)
|
||||
project(c_samples)
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCXX AND NOT ENABLE_NOISY_WARNINGS)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-function")
|
||||
endif()
|
||||
|
||||
ocv_include_modules(${OPENCV_C_SAMPLES_REQUIRED_DEPS})
|
||||
|
||||
# ---------------------------------------------
|
||||
# Define executable targets
|
||||
# ---------------------------------------------
|
||||
MACRO(OPENCV_DEFINE_C_EXAMPLE name srcs)
|
||||
set(the_target "example_${name}")
|
||||
add_executable(${the_target} ${srcs})
|
||||
target_link_libraries(${the_target} ${OPENCV_LINKER_LIBS} ${OPENCV_C_SAMPLES_REQUIRED_DEPS})
|
||||
|
||||
set_target_properties(${the_target} PROPERTIES
|
||||
OUTPUT_NAME "c-example-${name}"
|
||||
PROJECT_LABEL "(EXAMPLE) ${name}")
|
||||
|
||||
if(ENABLE_SOLUTION_FOLDERS)
|
||||
set_target_properties(${the_target} PROPERTIES FOLDER "samples//c")
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
if(MSVC AND NOT BUILD_SHARED_LIBS)
|
||||
set_target_properties(${the_target} PROPERTIES LINK_FLAGS "/NODEFAULTLIB:atlthunk.lib /NODEFAULTLIB:atlsd.lib /DEBUG")
|
||||
endif()
|
||||
install(TARGETS ${the_target}
|
||||
RUNTIME DESTINATION "${OPENCV_SAMPLES_BIN_INSTALL_PATH}/c" COMPONENT samples)
|
||||
endif()
|
||||
ENDMACRO()
|
||||
|
||||
file(GLOB cpp_samples RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp *.c)
|
||||
|
||||
foreach(sample_filename ${cpp_samples})
|
||||
get_filename_component(sample ${sample_filename} NAME_WE)
|
||||
OPENCV_DEFINE_C_EXAMPLE(${sample} ${sample_filename})
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
if(INSTALL_C_EXAMPLES AND NOT WIN32)
|
||||
file(GLOB C_SAMPLES *.c *.cpp *.jpg *.png *.data makefile.* build_all.sh *.dsp *.cmd )
|
||||
install(FILES ${C_SAMPLES}
|
||||
DESTINATION ${OPENCV_SAMPLES_SRC_INSTALL_PATH}/c
|
||||
PERMISSIONS OWNER_READ GROUP_READ WORLD_READ COMPONENT samples)
|
||||
endif ()
|
||||
|
Before Width: | Height: | Size: 372 B |
@@ -1,415 +0,0 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install, copy or use the software.
|
||||
//
|
||||
// Copyright (C) 2009, Farhad Dadgostar
|
||||
// Intel Corporation and third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of Intel Corporation may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include <iostream>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <ctime>
|
||||
#include "opencv2/contrib/compat.hpp"
|
||||
#include "opencv2/highgui/highgui_c.h"
|
||||
|
||||
#ifndef _CRT_SECURE_NO_WARNINGS
|
||||
# define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
|
||||
static void help(char **argv)
|
||||
{
|
||||
std::cout << "\nThis program demonstrates the contributed flesh detector CvAdaptiveSkinDetector which can be found in contrib.cpp\n"
|
||||
<< "Usage: " << std::endl <<
|
||||
argv[0] << " fileMask firstFrame lastFrame" << std::endl << std::endl <<
|
||||
"Example: " << std::endl <<
|
||||
argv[0] << " C:\\VideoSequences\\sample1\\right_view\\temp_%05d.jpg 0 1000" << std::endl <<
|
||||
" iterates through temp_00000.jpg to temp_01000.jpg" << std::endl << std::endl <<
|
||||
"If no parameter specified, this application will try to capture from the default Webcam." << std::endl <<
|
||||
"Please note: Background should not contain large surfaces with skin tone." <<
|
||||
"\n\n ESC will stop\n"
|
||||
"Using OpenCV version %s\n" << CV_VERSION << "\n"
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
class ASDFrameHolder
|
||||
{
|
||||
private:
|
||||
IplImage *image;
|
||||
double timeStamp;
|
||||
|
||||
public:
|
||||
ASDFrameHolder();
|
||||
virtual ~ASDFrameHolder();
|
||||
virtual void assignFrame(IplImage *sourceImage, double frameTime);
|
||||
inline IplImage *getImage();
|
||||
inline double getTimeStamp();
|
||||
virtual void setImage(IplImage *sourceImage);
|
||||
};
|
||||
|
||||
class ASDFrameSequencer
|
||||
{
|
||||
public:
|
||||
virtual ~ASDFrameSequencer();
|
||||
virtual IplImage *getNextImage();
|
||||
virtual void close();
|
||||
virtual bool isOpen();
|
||||
virtual void getFrameCaption(char *caption);
|
||||
};
|
||||
|
||||
class ASDCVFrameSequencer : public ASDFrameSequencer
|
||||
{
|
||||
protected:
|
||||
CvCapture *capture;
|
||||
|
||||
public:
|
||||
virtual IplImage *getNextImage();
|
||||
virtual void close();
|
||||
virtual bool isOpen();
|
||||
};
|
||||
|
||||
class ASDFrameSequencerWebCam : public ASDCVFrameSequencer
|
||||
{
|
||||
public:
|
||||
virtual bool open(int cameraIndex);
|
||||
};
|
||||
|
||||
class ASDFrameSequencerVideoFile : public ASDCVFrameSequencer
|
||||
{
|
||||
public:
|
||||
virtual bool open(const char *fileName);
|
||||
};
|
||||
|
||||
class ASDFrameSequencerImageFile : public ASDFrameSequencer {
|
||||
private:
|
||||
char sFileNameMask[2048];
|
||||
int nCurrentIndex, nStartIndex, nEndIndex;
|
||||
|
||||
public:
|
||||
virtual void open(const char *fileNameMask, int startIndex, int endIndex);
|
||||
virtual void getFrameCaption(char *caption);
|
||||
virtual IplImage *getNextImage();
|
||||
virtual void close();
|
||||
virtual bool isOpen();
|
||||
};
|
||||
|
||||
//-------------------- ASDFrameHolder -----------------------//
|
||||
ASDFrameHolder::ASDFrameHolder( )
|
||||
{
|
||||
image = NULL;
|
||||
timeStamp = 0;
|
||||
}
|
||||
|
||||
ASDFrameHolder::~ASDFrameHolder( )
|
||||
{
|
||||
cvReleaseImage(&image);
|
||||
}
|
||||
|
||||
void ASDFrameHolder::assignFrame(IplImage *sourceImage, double frameTime)
|
||||
{
|
||||
if (image != NULL)
|
||||
{
|
||||
cvReleaseImage(&image);
|
||||
image = NULL;
|
||||
}
|
||||
|
||||
image = cvCloneImage(sourceImage);
|
||||
timeStamp = frameTime;
|
||||
}
|
||||
|
||||
IplImage *ASDFrameHolder::getImage()
|
||||
{
|
||||
return image;
|
||||
}
|
||||
|
||||
double ASDFrameHolder::getTimeStamp()
|
||||
{
|
||||
return timeStamp;
|
||||
}
|
||||
|
||||
void ASDFrameHolder::setImage(IplImage *sourceImage)
|
||||
{
|
||||
image = sourceImage;
|
||||
}
|
||||
|
||||
|
||||
//-------------------- ASDFrameSequencer -----------------------//
|
||||
|
||||
ASDFrameSequencer::~ASDFrameSequencer()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
IplImage *ASDFrameSequencer::getNextImage()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ASDFrameSequencer::close()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool ASDFrameSequencer::isOpen()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void ASDFrameSequencer::getFrameCaption(char* /*caption*/) {
|
||||
return;
|
||||
}
|
||||
|
||||
IplImage* ASDCVFrameSequencer::getNextImage()
|
||||
{
|
||||
IplImage *image;
|
||||
|
||||
image = cvQueryFrame(capture);
|
||||
|
||||
if (image != NULL)
|
||||
{
|
||||
return cvCloneImage(image);
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void ASDCVFrameSequencer::close()
|
||||
{
|
||||
if (capture != NULL)
|
||||
{
|
||||
cvReleaseCapture(&capture);
|
||||
}
|
||||
}
|
||||
|
||||
bool ASDCVFrameSequencer::isOpen()
|
||||
{
|
||||
return (capture != NULL);
|
||||
}
|
||||
|
||||
|
||||
//-------------------- ASDFrameSequencerWebCam -----------------------//
|
||||
|
||||
bool ASDFrameSequencerWebCam::open(int cameraIndex)
|
||||
{
|
||||
close();
|
||||
|
||||
capture = cvCaptureFromCAM(cameraIndex);
|
||||
|
||||
if (!capture)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------- ASDFrameSequencerVideoFile -----------------------//
|
||||
|
||||
bool ASDFrameSequencerVideoFile::open(const char *fileName)
|
||||
{
|
||||
close();
|
||||
|
||||
capture = cvCaptureFromFile(fileName);
|
||||
if (!capture)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------- ASDFrameSequencerImageFile -----------------------//
|
||||
|
||||
void ASDFrameSequencerImageFile::open(const char *fileNameMask, int startIndex, int endIndex)
|
||||
{
|
||||
nCurrentIndex = startIndex-1;
|
||||
nStartIndex = startIndex;
|
||||
nEndIndex = endIndex;
|
||||
|
||||
std::sprintf(sFileNameMask, "%s", fileNameMask);
|
||||
}
|
||||
|
||||
void ASDFrameSequencerImageFile::getFrameCaption(char *caption) {
|
||||
std::sprintf(caption, sFileNameMask, nCurrentIndex);
|
||||
}
|
||||
|
||||
IplImage* ASDFrameSequencerImageFile::getNextImage()
|
||||
{
|
||||
char fileName[2048];
|
||||
|
||||
nCurrentIndex++;
|
||||
|
||||
if (nCurrentIndex > nEndIndex)
|
||||
return NULL;
|
||||
|
||||
std::sprintf(fileName, sFileNameMask, nCurrentIndex);
|
||||
|
||||
IplImage* img = cvLoadImage(fileName);
|
||||
|
||||
return img;
|
||||
}
|
||||
|
||||
void ASDFrameSequencerImageFile::close()
|
||||
{
|
||||
nCurrentIndex = nEndIndex+1;
|
||||
}
|
||||
|
||||
bool ASDFrameSequencerImageFile::isOpen()
|
||||
{
|
||||
return (nCurrentIndex <= nEndIndex);
|
||||
}
|
||||
|
||||
static void putTextWithShadow(IplImage *img, const char *str, CvPoint point, CvFont *font, CvScalar color = CV_RGB(255, 255, 128))
|
||||
{
|
||||
cvPutText(img, str, cvPoint(point.x-1,point.y-1), font, CV_RGB(0, 0, 0));
|
||||
cvPutText(img, str, point, font, color);
|
||||
}
|
||||
|
||||
#define ASD_RGB_SET_PIXEL(pointer, r, g, b) { (*pointer) = (unsigned char)b; (*(pointer+1)) = (unsigned char)g; (*(pointer+2)) = (unsigned char)r; }
|
||||
|
||||
#define ASD_RGB_GET_PIXEL(pointer, r, g, b) {b = (unsigned char)(*(pointer)); g = (unsigned char)(*(pointer+1)); r = (unsigned char)(*(pointer+2));}
|
||||
|
||||
static void displayBuffer(IplImage *rgbDestImage, IplImage *buffer, int rValue, int gValue, int bValue)
|
||||
{
|
||||
int x, y, nWidth, nHeight;
|
||||
double destX, destY, dx, dy;
|
||||
uchar c;
|
||||
unsigned char *pSrc;
|
||||
|
||||
nWidth = buffer->width;
|
||||
nHeight = buffer->height;
|
||||
|
||||
dx = double(rgbDestImage->width)/double(nWidth);
|
||||
dy = double(rgbDestImage->height)/double(nHeight);
|
||||
|
||||
destX = 0;
|
||||
for (x = 0; x < nWidth; x++)
|
||||
{
|
||||
destY = 0;
|
||||
for (y = 0; y < nHeight; y++)
|
||||
{
|
||||
c = ((uchar*)(buffer->imageData + buffer->widthStep*y))[x];
|
||||
|
||||
if (c)
|
||||
{
|
||||
pSrc = (unsigned char *)rgbDestImage->imageData + rgbDestImage->widthStep*int(destY) + (int(destX)*rgbDestImage->nChannels);
|
||||
ASD_RGB_SET_PIXEL(pSrc, rValue, gValue, bValue);
|
||||
}
|
||||
destY += dy;
|
||||
}
|
||||
destY = 0;
|
||||
destX += dx;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char** argv )
|
||||
{
|
||||
IplImage *img, *filterMask = NULL;
|
||||
CvAdaptiveSkinDetector filter(1, CvAdaptiveSkinDetector::MORPHING_METHOD_ERODE_DILATE);
|
||||
ASDFrameSequencer *sequencer;
|
||||
CvFont base_font;
|
||||
char caption[2048], s[256], windowName[256];
|
||||
long int clockTotal = 0, numFrames = 0;
|
||||
std::clock_t clock;
|
||||
|
||||
if (argc < 4)
|
||||
{
|
||||
help(argv);
|
||||
sequencer = new ASDFrameSequencerWebCam();
|
||||
(dynamic_cast<ASDFrameSequencerWebCam*>(sequencer))->open(-1);
|
||||
|
||||
if (! sequencer->isOpen())
|
||||
{
|
||||
std::cout << std::endl << "Error: Cannot initialize the default Webcam" << std::endl << std::endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sequencer = new ASDFrameSequencerImageFile();
|
||||
(dynamic_cast<ASDFrameSequencerImageFile*>(sequencer))->open(argv[1], std::atoi(argv[2]), std::atoi(argv[3]) ); // A sequence of images captured from video source, is stored here
|
||||
|
||||
}
|
||||
std::sprintf(windowName, "%s", "Adaptive Skin Detection Algorithm for Video Sequences");
|
||||
|
||||
cvNamedWindow(windowName, CV_WINDOW_AUTOSIZE);
|
||||
cvInitFont( &base_font, CV_FONT_VECTOR0, 0.5, 0.5);
|
||||
|
||||
// Usage:
|
||||
// c:\>CvASDSample "C:\VideoSequences\sample1\right_view\temp_%05d.jpg" 0 1000
|
||||
|
||||
std::cout << "Press ESC to stop." << std::endl << std::endl;
|
||||
while ((img = sequencer->getNextImage()) != 0)
|
||||
{
|
||||
numFrames++;
|
||||
|
||||
if (filterMask == NULL)
|
||||
{
|
||||
filterMask = cvCreateImage( cvSize(img->width, img->height), IPL_DEPTH_8U, 1);
|
||||
}
|
||||
clock = std::clock();
|
||||
filter.process(img, filterMask); // DETECT SKIN
|
||||
clockTotal += (std::clock() - clock);
|
||||
|
||||
displayBuffer(img, filterMask, 0, 255, 0);
|
||||
|
||||
sequencer->getFrameCaption(caption);
|
||||
std::sprintf(s, "%s - %d x %d", caption, img->width, img->height);
|
||||
putTextWithShadow(img, s, cvPoint(10, img->height-35), &base_font);
|
||||
|
||||
std::sprintf(s, "Average processing time per frame: %5.2fms", (double(clockTotal*1000/CLOCKS_PER_SEC))/numFrames);
|
||||
putTextWithShadow(img, s, cvPoint(10, img->height-15), &base_font);
|
||||
|
||||
cvShowImage (windowName, img);
|
||||
cvReleaseImage(&img);
|
||||
|
||||
if (cvWaitKey(1) == 27)
|
||||
break;
|
||||
}
|
||||
|
||||
sequencer->close();
|
||||
delete sequencer;
|
||||
|
||||
cvReleaseImage(&filterMask);
|
||||
|
||||
cvDestroyWindow(windowName);
|
||||
|
||||
std::cout << "Finished, " << numFrames << " frames processed." << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Before Width: | Height: | Size: 176 KiB |
@@ -1,241 +0,0 @@
|
||||
// Background average sample code done with averages and done with codebooks
|
||||
// (adapted from the OpenCV book sample)
|
||||
//
|
||||
// NOTE: To get the keyboard to work, you *have* to have one of the video windows be active
|
||||
// and NOT the consule window.
|
||||
//
|
||||
// Gary Bradski Oct 3, 2008.
|
||||
//
|
||||
/* *************** License:**************************
|
||||
Oct. 3, 2008
|
||||
Right to use this code in any way you want without warrenty, support or any guarentee of it working.
|
||||
|
||||
BOOK: It would be nice if you cited it:
|
||||
Learning OpenCV: Computer Vision with the OpenCV Library
|
||||
by Gary Bradski and Adrian Kaehler
|
||||
Published by O'Reilly Media, October 3, 2008
|
||||
|
||||
AVAILABLE AT:
|
||||
http://www.amazon.com/Learning-OpenCV-Computer-Vision-Library/dp/0596516134
|
||||
Or: http://oreilly.com/catalog/9780596516130/
|
||||
ISBN-10: 0596516134 or: ISBN-13: 978-0596516130
|
||||
************************************************** */
|
||||
#include "opencv2/core.hpp"
|
||||
#include "opencv2/core/utility.hpp"
|
||||
#include "opencv2/video/background_segm.hpp"
|
||||
#include "opencv2/imgproc/imgproc_c.h"
|
||||
#include "opencv2/highgui/highgui_c.h"
|
||||
#include "opencv2/legacy.hpp"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
|
||||
//VARIABLES for CODEBOOK METHOD:
|
||||
CvBGCodeBookModel* model = 0;
|
||||
const int NCHANNELS = 3;
|
||||
bool ch[NCHANNELS]={true,true,true}; // This sets what channels should be adjusted for background bounds
|
||||
|
||||
static void help()
|
||||
{
|
||||
printf("\nLearn background and find foreground using simple average and average difference learning method:\n"
|
||||
"Originally from the book: Learning OpenCV by O'Reilly press\n"
|
||||
"\nUSAGE:\n"
|
||||
" bgfg_codebook [--nframes(-nf)=300] [--movie_filename(-mf)=tree.avi] [--camera(-c), use camera or not]\n"
|
||||
"***Keep the focus on the video windows, NOT the consol***\n\n"
|
||||
"INTERACTIVE PARAMETERS:\n"
|
||||
"\tESC,q,Q - quit the program\n"
|
||||
"\th - print this help\n"
|
||||
"\tp - pause toggle\n"
|
||||
"\ts - single step\n"
|
||||
"\tr - run mode (single step off)\n"
|
||||
"=== AVG PARAMS ===\n"
|
||||
"\t- - bump high threshold UP by 0.25\n"
|
||||
"\t= - bump high threshold DOWN by 0.25\n"
|
||||
"\t[ - bump low threshold UP by 0.25\n"
|
||||
"\t] - bump low threshold DOWN by 0.25\n"
|
||||
"=== CODEBOOK PARAMS ===\n"
|
||||
"\ty,u,v- only adjust channel 0(y) or 1(u) or 2(v) respectively\n"
|
||||
"\ta - adjust all 3 channels at once\n"
|
||||
"\tb - adjust both 2 and 3 at once\n"
|
||||
"\ti,o - bump upper threshold up,down by 1\n"
|
||||
"\tk,l - bump lower threshold up,down by 1\n"
|
||||
"\tSPACE - reset the model\n"
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
//USAGE: ch9_background startFrameCollection# endFrameCollection# [movie filename, else from camera]
|
||||
//If from AVI, then optionally add HighAvg, LowAvg, HighCB_Y LowCB_Y HighCB_U LowCB_U HighCB_V LowCB_V
|
||||
//
|
||||
const char *keys =
|
||||
{
|
||||
"{nf nframes |300 |frames number}"
|
||||
"{c camera |false |use the camera or not}"
|
||||
"{mf movie_file|tree.avi |used movie video file}"
|
||||
};
|
||||
int main(int argc, const char** argv)
|
||||
{
|
||||
help();
|
||||
|
||||
CommandLineParser parser(argc, argv, keys);
|
||||
int nframesToLearnBG = parser.get<int>("nf");
|
||||
bool useCamera = parser.has("c");
|
||||
string filename = parser.get<string>("mf");
|
||||
IplImage* rawImage = 0, *yuvImage = 0; //yuvImage is for codebook method
|
||||
IplImage *ImaskCodeBook = 0,*ImaskCodeBookCC = 0;
|
||||
CvCapture* capture = 0;
|
||||
|
||||
int c, n, nframes = 0;
|
||||
|
||||
model = cvCreateBGCodeBookModel();
|
||||
|
||||
//Set color thresholds to default values
|
||||
model->modMin[0] = 3;
|
||||
model->modMin[1] = model->modMin[2] = 3;
|
||||
model->modMax[0] = 10;
|
||||
model->modMax[1] = model->modMax[2] = 10;
|
||||
model->cbBounds[0] = model->cbBounds[1] = model->cbBounds[2] = 10;
|
||||
|
||||
bool pause = false;
|
||||
bool singlestep = false;
|
||||
|
||||
if( useCamera )
|
||||
{
|
||||
printf("Capture from camera\n");
|
||||
capture = cvCaptureFromCAM( 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Capture from file %s\n",filename.c_str());
|
||||
capture = cvCreateFileCapture( filename.c_str() );
|
||||
}
|
||||
|
||||
if( !capture )
|
||||
{
|
||||
printf( "Can not initialize video capturing\n\n" );
|
||||
help();
|
||||
return -1;
|
||||
}
|
||||
|
||||
//MAIN PROCESSING LOOP:
|
||||
for(;;)
|
||||
{
|
||||
if( !pause )
|
||||
{
|
||||
rawImage = cvQueryFrame( capture );
|
||||
++nframes;
|
||||
if(!rawImage)
|
||||
break;
|
||||
}
|
||||
if( singlestep )
|
||||
pause = true;
|
||||
|
||||
//First time:
|
||||
if( nframes == 1 && rawImage )
|
||||
{
|
||||
// CODEBOOK METHOD ALLOCATION
|
||||
yuvImage = cvCloneImage(rawImage);
|
||||
ImaskCodeBook = cvCreateImage( cvGetSize(rawImage), IPL_DEPTH_8U, 1 );
|
||||
ImaskCodeBookCC = cvCreateImage( cvGetSize(rawImage), IPL_DEPTH_8U, 1 );
|
||||
cvSet(ImaskCodeBook,cvScalar(255));
|
||||
|
||||
cvNamedWindow( "Raw", 1 );
|
||||
cvNamedWindow( "ForegroundCodeBook",1);
|
||||
cvNamedWindow( "CodeBook_ConnectComp",1);
|
||||
}
|
||||
|
||||
// If we've got an rawImage and are good to go:
|
||||
if( rawImage )
|
||||
{
|
||||
cvCvtColor( rawImage, yuvImage, CV_BGR2YCrCb );//YUV For codebook method
|
||||
//This is where we build our background model
|
||||
if( !pause && nframes-1 < nframesToLearnBG )
|
||||
cvBGCodeBookUpdate( model, yuvImage );
|
||||
|
||||
if( nframes-1 == nframesToLearnBG )
|
||||
cvBGCodeBookClearStale( model, model->t/2 );
|
||||
|
||||
//Find the foreground if any
|
||||
if( nframes-1 >= nframesToLearnBG )
|
||||
{
|
||||
// Find foreground by codebook method
|
||||
cvBGCodeBookDiff( model, yuvImage, ImaskCodeBook );
|
||||
// This part just to visualize bounding boxes and centers if desired
|
||||
cvCopy(ImaskCodeBook,ImaskCodeBookCC);
|
||||
cvSegmentFGMask( ImaskCodeBookCC );
|
||||
}
|
||||
//Display
|
||||
cvShowImage( "Raw", rawImage );
|
||||
cvShowImage( "ForegroundCodeBook",ImaskCodeBook);
|
||||
cvShowImage( "CodeBook_ConnectComp",ImaskCodeBookCC);
|
||||
}
|
||||
|
||||
// User input:
|
||||
c = cvWaitKey(10)&0xFF;
|
||||
c = tolower(c);
|
||||
// End processing on ESC, q or Q
|
||||
if(c == 27 || c == 'q')
|
||||
break;
|
||||
//Else check for user input
|
||||
switch( c )
|
||||
{
|
||||
case 'h':
|
||||
help();
|
||||
break;
|
||||
case 'p':
|
||||
pause = !pause;
|
||||
break;
|
||||
case 's':
|
||||
singlestep = !singlestep;
|
||||
pause = false;
|
||||
break;
|
||||
case 'r':
|
||||
pause = false;
|
||||
singlestep = false;
|
||||
break;
|
||||
case ' ':
|
||||
cvBGCodeBookClearStale( model, 0 );
|
||||
nframes = 0;
|
||||
break;
|
||||
//CODEBOOK PARAMS
|
||||
case 'y': case '0':
|
||||
case 'u': case '1':
|
||||
case 'v': case '2':
|
||||
case 'a': case '3':
|
||||
case 'b':
|
||||
ch[0] = c == 'y' || c == '0' || c == 'a' || c == '3';
|
||||
ch[1] = c == 'u' || c == '1' || c == 'a' || c == '3' || c == 'b';
|
||||
ch[2] = c == 'v' || c == '2' || c == 'a' || c == '3' || c == 'b';
|
||||
printf("CodeBook YUV Channels active: %d, %d, %d\n", ch[0], ch[1], ch[2] );
|
||||
break;
|
||||
case 'i': //modify max classification bounds (max bound goes higher)
|
||||
case 'o': //modify max classification bounds (max bound goes lower)
|
||||
case 'k': //modify min classification bounds (min bound goes lower)
|
||||
case 'l': //modify min classification bounds (min bound goes higher)
|
||||
{
|
||||
uchar* ptr = c == 'i' || c == 'o' ? model->modMax : model->modMin;
|
||||
for(n=0; n<NCHANNELS; n++)
|
||||
{
|
||||
if( ch[n] )
|
||||
{
|
||||
int v = ptr[n] + (c == 'i' || c == 'l' ? 1 : -1);
|
||||
ptr[n] = cv::saturate_cast<uchar>(v);
|
||||
}
|
||||
printf("%d,", ptr[n]);
|
||||
}
|
||||
printf(" CodeBook %s Side\n", c == 'i' || c == 'o' ? "High" : "Low" );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cvReleaseCapture( &capture );
|
||||
cvDestroyWindow( "Raw" );
|
||||
cvDestroyWindow( "ForegroundCodeBook");
|
||||
cvDestroyWindow( "CodeBook_ConnectComp");
|
||||
return 0;
|
||||
}
|
||||
@@ -1,755 +0,0 @@
|
||||
#include "opencv2/video/background_segm.hpp"
|
||||
#include "opencv2/legacy/blobtrack.hpp"
|
||||
#include "opencv2/legacy/legacy.hpp"
|
||||
#include <opencv2/highgui/highgui_c.h>
|
||||
#include <opencv2/imgproc/imgproc_c.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* Select appropriate case insensitive string comparison function: */
|
||||
#if defined WIN32 || defined _MSC_VER
|
||||
# define MY_STRNICMP _strnicmp
|
||||
# define MY_STRICMP _stricmp
|
||||
# define MY_STRDUP _strdup
|
||||
#else
|
||||
# define MY_STRNICMP strncasecmp
|
||||
# define MY_STRICMP strcasecmp
|
||||
# define MY_STRDUP strdup
|
||||
#endif
|
||||
|
||||
/* List of foreground (FG) DETECTION modules: */
|
||||
static CvFGDetector* cvCreateFGDetector0 () { return cvCreateFGDetectorBase(CV_BG_MODEL_FGD, NULL); }
|
||||
static CvFGDetector* cvCreateFGDetector0Simple() { return cvCreateFGDetectorBase(CV_BG_MODEL_FGD_SIMPLE, NULL); }
|
||||
static CvFGDetector* cvCreateFGDetector1 () { return cvCreateFGDetectorBase(CV_BG_MODEL_MOG, NULL); }
|
||||
|
||||
typedef struct DefModule_FGDetector
|
||||
{
|
||||
CvFGDetector* (*create)();
|
||||
const char* nickname;
|
||||
const char* description;
|
||||
} DefModule_FGDetector;
|
||||
|
||||
DefModule_FGDetector FGDetector_Modules[] =
|
||||
{
|
||||
{cvCreateFGDetector0,"FG_0","Foreground Object Detection from Videos Containing Complex Background. ACM MM2003."},
|
||||
{cvCreateFGDetector0Simple,"FG_0S","Simplified version of FG_0"},
|
||||
{cvCreateFGDetector1,"FG_1","Adaptive background mixture models for real-time tracking. CVPR1999"},
|
||||
{NULL,NULL,NULL}
|
||||
};
|
||||
|
||||
/* List of BLOB DETECTION modules: */
|
||||
typedef struct DefModule_BlobDetector
|
||||
{
|
||||
CvBlobDetector* (*create)();
|
||||
const char* nickname;
|
||||
const char* description;
|
||||
} DefModule_BlobDetector;
|
||||
|
||||
DefModule_BlobDetector BlobDetector_Modules[] =
|
||||
{
|
||||
{cvCreateBlobDetectorCC,"BD_CC","Detect new blob by tracking CC of FG mask"},
|
||||
{cvCreateBlobDetectorSimple,"BD_Simple","Detect new blob by uniform moving of connected components of FG mask"},
|
||||
{NULL,NULL,NULL}
|
||||
};
|
||||
|
||||
/* List of BLOB TRACKING modules: */
|
||||
typedef struct DefModule_BlobTracker
|
||||
{
|
||||
CvBlobTracker* (*create)();
|
||||
const char* nickname;
|
||||
const char* description;
|
||||
} DefModule_BlobTracker;
|
||||
|
||||
DefModule_BlobTracker BlobTracker_Modules[] =
|
||||
{
|
||||
{cvCreateBlobTrackerCCMSPF,"CCMSPF","connected component tracking and MSPF resolver for collision"},
|
||||
{cvCreateBlobTrackerCC,"CC","Simple connected component tracking"},
|
||||
{cvCreateBlobTrackerMS,"MS","Mean shift algorithm "},
|
||||
{cvCreateBlobTrackerMSFG,"MSFG","Mean shift algorithm with FG mask using"},
|
||||
{cvCreateBlobTrackerMSPF,"MSPF","Particle filtering based on MS weight"},
|
||||
{NULL,NULL,NULL}
|
||||
};
|
||||
|
||||
/* List of BLOB TRAJECTORY GENERATION modules: */
|
||||
typedef struct DefModule_BlobTrackGen
|
||||
{
|
||||
CvBlobTrackGen* (*create)();
|
||||
const char* nickname;
|
||||
const char* description;
|
||||
} DefModule_BlobTrackGen;
|
||||
|
||||
DefModule_BlobTrackGen BlobTrackGen_Modules[] =
|
||||
{
|
||||
{cvCreateModuleBlobTrackGenYML,"YML","Generate track record in YML format as synthetic video data"},
|
||||
{cvCreateModuleBlobTrackGen1,"RawTracks","Generate raw track record (x,y,sx,sy),()... in each line"},
|
||||
{NULL,NULL,NULL}
|
||||
};
|
||||
|
||||
/* List of BLOB TRAJECTORY POST PROCESSING modules: */
|
||||
typedef struct DefModule_BlobTrackPostProc
|
||||
{
|
||||
CvBlobTrackPostProc* (*create)();
|
||||
const char* nickname;
|
||||
const char* description;
|
||||
} DefModule_BlobTrackPostProc;
|
||||
|
||||
DefModule_BlobTrackPostProc BlobTrackPostProc_Modules[] =
|
||||
{
|
||||
{cvCreateModuleBlobTrackPostProcKalman,"Kalman","Kalman filtering of blob position and size"},
|
||||
{NULL,"None","No post processing filter"},
|
||||
// {cvCreateModuleBlobTrackPostProcTimeAverRect,"TimeAverRect","Average by time using rectangle window"},
|
||||
// {cvCreateModuleBlobTrackPostProcTimeAverExp,"TimeAverExp","Average by time using exponential window"},
|
||||
{NULL,NULL,NULL}
|
||||
};
|
||||
|
||||
/* List of BLOB TRAJECTORY ANALYSIS modules: */
|
||||
CvBlobTrackAnalysis* cvCreateModuleBlobTrackAnalysisDetector();
|
||||
|
||||
typedef struct DefModule_BlobTrackAnalysis
|
||||
{
|
||||
CvBlobTrackAnalysis* (*create)();
|
||||
const char* nickname;
|
||||
const char* description;
|
||||
} DefModule_BlobTrackAnalysis;
|
||||
|
||||
DefModule_BlobTrackAnalysis BlobTrackAnalysis_Modules[] =
|
||||
{
|
||||
{cvCreateModuleBlobTrackAnalysisHistPVS,"HistPVS","Histogram of 5D feature vector analysis (x,y,vx,vy,state)"},
|
||||
{NULL,"None","No trajectory analiser"},
|
||||
{cvCreateModuleBlobTrackAnalysisHistP,"HistP","Histogram of 2D feature vector analysis (x,y)"},
|
||||
{cvCreateModuleBlobTrackAnalysisHistPV,"HistPV","Histogram of 4D feature vector analysis (x,y,vx,vy)"},
|
||||
{cvCreateModuleBlobTrackAnalysisHistSS,"HistSS","Histogram of 4D feature vector analysis (startpos,endpos)"},
|
||||
{cvCreateModuleBlobTrackAnalysisTrackDist,"TrackDist","Compare tracks directly"},
|
||||
{cvCreateModuleBlobTrackAnalysisIOR,"IOR","Integrator (by OR operation) of several analysers "},
|
||||
{NULL,NULL,NULL}
|
||||
};
|
||||
|
||||
/* List of Blob Trajectory ANALYSIS modules: */
|
||||
/*================= END MODULES DECRIPTION ===================================*/
|
||||
|
||||
/* Run pipeline on all frames: */
|
||||
static int RunBlobTrackingAuto( CvCapture* pCap, CvBlobTrackerAuto* pTracker,char* fgavi_name = NULL, char* btavi_name = NULL )
|
||||
{
|
||||
int OneFrameProcess = 0;
|
||||
int key;
|
||||
int FrameNum = 0;
|
||||
CvVideoWriter* pFGAvi = NULL;
|
||||
CvVideoWriter* pBTAvi = NULL;
|
||||
|
||||
//cvNamedWindow( "FG", 0 );
|
||||
|
||||
/* Main loop: */
|
||||
for( FrameNum=0; pCap && (key=cvWaitKey(OneFrameProcess?0:1))!=27;
|
||||
FrameNum++)
|
||||
{ /* Main loop: */
|
||||
IplImage* pImg = NULL;
|
||||
IplImage* pMask = NULL;
|
||||
|
||||
if(key!=-1)
|
||||
{
|
||||
OneFrameProcess = 1;
|
||||
if(key=='r')OneFrameProcess = 0;
|
||||
}
|
||||
|
||||
pImg = cvQueryFrame(pCap);
|
||||
if(pImg == NULL) break;
|
||||
|
||||
|
||||
/* Process: */
|
||||
pTracker->Process(pImg, pMask);
|
||||
|
||||
if(fgavi_name)
|
||||
if(pTracker->GetFGMask())
|
||||
{ /* Debug FG: */
|
||||
IplImage* pFG = pTracker->GetFGMask();
|
||||
CvSize S = cvSize(pFG->width,pFG->height);
|
||||
static IplImage* pI = NULL;
|
||||
|
||||
if(pI==NULL)pI = cvCreateImage(S,pFG->depth,3);
|
||||
cvCvtColor( pFG, pI, CV_GRAY2BGR );
|
||||
|
||||
if(fgavi_name)
|
||||
{ /* Save fg to avi file: */
|
||||
if(pFGAvi==NULL)
|
||||
{
|
||||
pFGAvi=cvCreateVideoWriter(
|
||||
fgavi_name,
|
||||
CV_FOURCC('x','v','i','d'),
|
||||
25,
|
||||
S );
|
||||
}
|
||||
cvWriteFrame( pFGAvi, pI );
|
||||
}
|
||||
|
||||
if(pTracker->GetBlobNum()>0)
|
||||
{ /* Draw detected blobs: */
|
||||
int i;
|
||||
for(i=pTracker->GetBlobNum();i>0;i--)
|
||||
{
|
||||
CvBlob* pB = pTracker->GetBlob(i-1);
|
||||
CvPoint p = cvPointFrom32f(CV_BLOB_CENTER(pB));
|
||||
CvSize s = cvSize(MAX(1,cvRound(CV_BLOB_RX(pB))), MAX(1,cvRound(CV_BLOB_RY(pB))));
|
||||
int c = cvRound(255*pTracker->GetState(CV_BLOB_ID(pB)));
|
||||
cvEllipse( pI,
|
||||
p,
|
||||
s,
|
||||
0, 0, 360,
|
||||
CV_RGB(c,255-c,0), cvRound(1+(3*c)/255) );
|
||||
} /* Next blob: */;
|
||||
}
|
||||
|
||||
cvNamedWindow( "FG",0);
|
||||
cvShowImage( "FG",pI);
|
||||
} /* Debug FG. */
|
||||
|
||||
|
||||
/* Draw debug info: */
|
||||
if(pImg)
|
||||
{ /* Draw all information about test sequence: */
|
||||
char str[1024];
|
||||
int line_type = CV_AA; // Change it to 8 to see non-antialiased graphics.
|
||||
CvFont font;
|
||||
int i;
|
||||
IplImage* pI = cvCloneImage(pImg);
|
||||
|
||||
cvInitFont( &font, CV_FONT_HERSHEY_PLAIN, 0.7, 0.7, 0, 1, line_type );
|
||||
|
||||
for(i=pTracker->GetBlobNum(); i>0; i--)
|
||||
{
|
||||
CvSize TextSize;
|
||||
CvBlob* pB = pTracker->GetBlob(i-1);
|
||||
CvPoint p = cvPoint(cvRound(pB->x*256),cvRound(pB->y*256));
|
||||
CvSize s = cvSize(MAX(1,cvRound(CV_BLOB_RX(pB)*256)), MAX(1,cvRound(CV_BLOB_RY(pB)*256)));
|
||||
int c = cvRound(255*pTracker->GetState(CV_BLOB_ID(pB)));
|
||||
|
||||
cvEllipse( pI,
|
||||
p,
|
||||
s,
|
||||
0, 0, 360,
|
||||
CV_RGB(c,255-c,0), cvRound(1+(3*0)/255), CV_AA, 8 );
|
||||
|
||||
p.x >>= 8;
|
||||
p.y >>= 8;
|
||||
s.width >>= 8;
|
||||
s.height >>= 8;
|
||||
sprintf(str,"%03d",CV_BLOB_ID(pB));
|
||||
cvGetTextSize( str, &font, &TextSize, NULL );
|
||||
p.y -= s.height;
|
||||
cvPutText( pI, str, p, &font, CV_RGB(0,255,255));
|
||||
{
|
||||
const char* pS = pTracker->GetStateDesc(CV_BLOB_ID(pB));
|
||||
|
||||
if(pS)
|
||||
{
|
||||
char* pStr = MY_STRDUP(pS);
|
||||
char* pStrFree = pStr;
|
||||
|
||||
while (pStr && strlen(pStr) > 0)
|
||||
{
|
||||
char* str_next = strchr(pStr,'\n');
|
||||
|
||||
if(str_next)
|
||||
{
|
||||
str_next[0] = 0;
|
||||
str_next++;
|
||||
}
|
||||
|
||||
p.y += TextSize.height+1;
|
||||
cvPutText( pI, pStr, p, &font, CV_RGB(0,255,255));
|
||||
pStr = str_next;
|
||||
}
|
||||
free(pStrFree);
|
||||
}
|
||||
}
|
||||
|
||||
} /* Next blob. */;
|
||||
|
||||
cvNamedWindow( "Tracking", 0);
|
||||
cvShowImage( "Tracking",pI );
|
||||
|
||||
if(btavi_name && pI)
|
||||
{ /* Save to avi file: */
|
||||
CvSize S = cvSize(pI->width,pI->height);
|
||||
if(pBTAvi==NULL)
|
||||
{
|
||||
pBTAvi=cvCreateVideoWriter(
|
||||
btavi_name,
|
||||
CV_FOURCC('x','v','i','d'),
|
||||
25,
|
||||
S );
|
||||
}
|
||||
cvWriteFrame( pBTAvi, pI );
|
||||
}
|
||||
|
||||
cvReleaseImage(&pI);
|
||||
} /* Draw all information about test sequence. */
|
||||
} /* Main loop. */
|
||||
|
||||
if(pFGAvi)cvReleaseVideoWriter( &pFGAvi );
|
||||
if(pBTAvi)cvReleaseVideoWriter( &pBTAvi );
|
||||
return 0;
|
||||
} /* RunBlobTrackingAuto */
|
||||
|
||||
/* Read parameters from command line
|
||||
* and transfer to specified module:
|
||||
*/
|
||||
static void set_params(int argc, char* argv[], CvVSModule* pM, const char* prefix, const char* module)
|
||||
{
|
||||
int prefix_len = (int)strlen(prefix);
|
||||
int i;
|
||||
for(i=0; i<argc; ++i)
|
||||
{
|
||||
int j;
|
||||
char* ptr_eq = NULL;
|
||||
int cmd_param_len=0;
|
||||
char* cmd = argv[i];
|
||||
if(MY_STRNICMP(prefix,cmd,prefix_len)!=0) continue;
|
||||
cmd += prefix_len;
|
||||
if(cmd[0]!=':')continue;
|
||||
cmd++;
|
||||
|
||||
ptr_eq = strchr(cmd,'=');
|
||||
if(ptr_eq)
|
||||
cmd_param_len = (int)(ptr_eq-cmd);
|
||||
|
||||
for(j=0; ; ++j)
|
||||
{
|
||||
int param_len;
|
||||
const char* param = pM->GetParamName(j);
|
||||
if(param==NULL) break;
|
||||
param_len = (int)strlen(param);
|
||||
if(cmd_param_len!=param_len) continue;
|
||||
if(MY_STRNICMP(param,cmd,param_len)!=0) continue;
|
||||
cmd+=param_len;
|
||||
if(cmd[0]!='=')continue;
|
||||
cmd++;
|
||||
pM->SetParamStr(param,cmd);
|
||||
printf("%s:%s param set to %g\n",module,param,pM->GetParam(param));
|
||||
}
|
||||
}
|
||||
|
||||
pM->ParamUpdate();
|
||||
|
||||
} /* set_params */
|
||||
|
||||
/* Print all parameter values for given module: */
|
||||
static void print_params(CvVSModule* pM, const char* module, const char* log_name)
|
||||
{
|
||||
FILE* log = log_name?fopen(log_name,"at"):NULL;
|
||||
int i;
|
||||
if(pM->GetParamName(0) == NULL ) return;
|
||||
|
||||
|
||||
printf("%s(%s) module parameters:\n",module,pM->GetNickName());
|
||||
if(log)
|
||||
fprintf(log,"%s(%s) module parameters:\n",module,pM->GetNickName());
|
||||
|
||||
for (i=0; ; ++i)
|
||||
{
|
||||
const char* param = pM->GetParamName(i);
|
||||
const char* str = param?pM->GetParamStr(param):NULL;
|
||||
if(param == NULL)break;
|
||||
if(str)
|
||||
{
|
||||
printf(" %s: %s\n",param,str);
|
||||
if(log)
|
||||
fprintf(log," %s: %s\n",param,str);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf(" %s: %g\n",param,pM->GetParam(param));
|
||||
if(log)
|
||||
fprintf(log," %s: %g\n",param,pM->GetParam(param));
|
||||
}
|
||||
}
|
||||
|
||||
if(log) fclose(log);
|
||||
|
||||
} /* print_params */
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{ /* Main function: */
|
||||
CvCapture* pCap = NULL;
|
||||
CvBlobTrackerAutoParam1 param = {0,0,0,0,0,0,0,0};
|
||||
CvBlobTrackerAuto* pTracker = NULL;
|
||||
|
||||
//float scale = 1;
|
||||
const char* scale_name = NULL;
|
||||
char* yml_name = NULL;
|
||||
char** yml_video_names = NULL;
|
||||
int yml_video_num = 0;
|
||||
char* avi_name = NULL;
|
||||
const char* fg_name = NULL;
|
||||
char* fgavi_name = NULL;
|
||||
char* btavi_name = NULL;
|
||||
const char* bd_name = NULL;
|
||||
const char* bt_name = NULL;
|
||||
const char* btgen_name = NULL;
|
||||
const char* btpp_name = NULL;
|
||||
const char* bta_name = NULL;
|
||||
char* bta_data_name = NULL;
|
||||
char* track_name = NULL;
|
||||
//char* comment_name = NULL;
|
||||
char* FGTrainFrames = NULL;
|
||||
char* log_name = NULL;
|
||||
char* savestate_name = NULL;
|
||||
char* loadstate_name = NULL;
|
||||
const char* bt_corr = NULL;
|
||||
DefModule_FGDetector* pFGModule = NULL;
|
||||
DefModule_BlobDetector* pBDModule = NULL;
|
||||
DefModule_BlobTracker* pBTModule = NULL;
|
||||
DefModule_BlobTrackPostProc* pBTPostProcModule = NULL;
|
||||
DefModule_BlobTrackGen* pBTGenModule = NULL;
|
||||
DefModule_BlobTrackAnalysis* pBTAnalysisModule = NULL;
|
||||
|
||||
cvInitSystem(argc, argv);
|
||||
|
||||
if(argc < 2)
|
||||
{ /* Print help: */
|
||||
int i;
|
||||
printf("blobtrack [fg=<fg_name>] [bd=<bd_name>]\n"
|
||||
" [bt=<bt_name>] [btpp=<btpp_name>]\n"
|
||||
" [bta=<bta_name>\n"
|
||||
" [bta_data=<bta_data_name>\n"
|
||||
" [bt_corr=<bt_corr_way>]\n"
|
||||
" [btgen=<btgen_name>]\n"
|
||||
" [track=<track_file_name>]\n"
|
||||
" [scale=<scale val>] [noise=<noise_name>] [IVar=<IVar_name>]\n"
|
||||
" [FGTrainFrames=<FGTrainFrames>]\n"
|
||||
" [btavi=<avi output>] [fgavi=<avi output on FG>]\n"
|
||||
" <avi_file>\n");
|
||||
|
||||
printf(" <bt_corr_way> is the method of blob position correction for the \"Blob Tracking\" module\n"
|
||||
" <bt_corr_way>=none,PostProcRes\n"
|
||||
" <FGTrainFrames> is number of frames for FG training\n"
|
||||
" <track_file_name> is file name for save tracked trajectories\n"
|
||||
" <bta_data> is file name for data base of trajectory analysis module\n"
|
||||
" <avi_file> is file name of avi to process by BlobTrackerAuto\n");
|
||||
|
||||
puts("\nModules:");
|
||||
#define PR(_name,_m,_mt)\
|
||||
printf("<%s> is \"%s\" module name and can be:\n",_name,_mt);\
|
||||
for(i=0; _m[i].nickname; ++i)\
|
||||
{\
|
||||
printf(" %d. %s",i+1,_m[i].nickname);\
|
||||
if(_m[i].description)printf(" - %s",_m[i].description);\
|
||||
printf("\n");\
|
||||
}
|
||||
|
||||
PR("fg_name",FGDetector_Modules,"FG/BG Detection");
|
||||
PR("bd_name",BlobDetector_Modules,"Blob Entrance Detection");
|
||||
PR("bt_name",BlobTracker_Modules,"Blob Tracking");
|
||||
PR("btpp_name",BlobTrackPostProc_Modules, "Blob Trajectory Post Processing");
|
||||
PR("btgen_name",BlobTrackGen_Modules, "Blob Trajectory Generation");
|
||||
PR("bta_name",BlobTrackAnalysis_Modules, "Blob Trajectory Analysis");
|
||||
#undef PR
|
||||
return 0;
|
||||
} /* Print help. */
|
||||
|
||||
{ /* Parse arguments: */
|
||||
int i;
|
||||
for(i=1; i<argc; ++i)
|
||||
{
|
||||
int bParsed = 0;
|
||||
size_t len = strlen(argv[i]);
|
||||
#define RO(_n1,_n2) if(strncmp(argv[i],_n1,strlen(_n1))==0) {_n2 = argv[i]+strlen(_n1);bParsed=1;};
|
||||
RO("fg=",fg_name);
|
||||
RO("fgavi=",fgavi_name);
|
||||
RO("btavi=",btavi_name);
|
||||
RO("bd=",bd_name);
|
||||
RO("bt=",bt_name);
|
||||
RO("bt_corr=",bt_corr);
|
||||
RO("btpp=",btpp_name);
|
||||
RO("bta=",bta_name);
|
||||
RO("bta_data=",bta_data_name);
|
||||
RO("btgen=",btgen_name);
|
||||
RO("track=",track_name);
|
||||
//RO("comment=",comment_name);
|
||||
RO("FGTrainFrames=",FGTrainFrames);
|
||||
RO("log=",log_name);
|
||||
RO("savestate=",savestate_name);
|
||||
RO("loadstate=",loadstate_name);
|
||||
#undef RO
|
||||
{
|
||||
char* ext = argv[i] + len-4;
|
||||
if( strrchr(argv[i],'=') == NULL &&
|
||||
!bParsed &&
|
||||
(len>3 && (MY_STRICMP(ext,".avi") == 0 )))
|
||||
{
|
||||
avi_name = argv[i];
|
||||
break;
|
||||
}
|
||||
} /* Next argument. */
|
||||
}
|
||||
} /* Parse arguments. */
|
||||
|
||||
if(track_name)
|
||||
{ /* Set Trajectory Generator module: */
|
||||
int i;
|
||||
if(!btgen_name)btgen_name=BlobTrackGen_Modules[0].nickname;
|
||||
|
||||
for(i=0; BlobTrackGen_Modules[i].nickname; ++i)
|
||||
{
|
||||
if(MY_STRICMP(BlobTrackGen_Modules[i].nickname,btgen_name)==0)
|
||||
pBTGenModule = BlobTrackGen_Modules + i;
|
||||
}
|
||||
} /* Set Trajectory Generato module. */
|
||||
|
||||
/* Initialize postprocessing module if tracker
|
||||
* correction by postprocessing is required.
|
||||
*/
|
||||
if(bt_corr && MY_STRICMP(bt_corr,"PostProcRes")!=0 && !btpp_name)
|
||||
{
|
||||
btpp_name = bt_corr;
|
||||
if(MY_STRICMP(btpp_name,"none")!=0)bt_corr = "PostProcRes";
|
||||
}
|
||||
|
||||
{ /* Set default parameters for one processing: */
|
||||
if(!bt_corr) bt_corr = "none";
|
||||
if(!fg_name) fg_name = FGDetector_Modules[0].nickname;
|
||||
if(!bd_name) bd_name = BlobDetector_Modules[0].nickname;
|
||||
if(!bt_name) bt_name = BlobTracker_Modules[0].nickname;
|
||||
if(!btpp_name) btpp_name = BlobTrackPostProc_Modules[0].nickname;
|
||||
if(!bta_name) bta_name = BlobTrackAnalysis_Modules[0].nickname;
|
||||
if(!scale_name) scale_name = "1";
|
||||
}
|
||||
|
||||
// if(scale_name)
|
||||
// scale = (float)atof(scale_name);
|
||||
|
||||
for(pFGModule=FGDetector_Modules; pFGModule->nickname; ++pFGModule)
|
||||
if( fg_name && MY_STRICMP(fg_name,pFGModule->nickname)==0 ) break;
|
||||
|
||||
for(pBDModule=BlobDetector_Modules; pBDModule->nickname; ++pBDModule)
|
||||
if( bd_name && MY_STRICMP(bd_name,pBDModule->nickname)==0 ) break;
|
||||
|
||||
for(pBTModule=BlobTracker_Modules; pBTModule->nickname; ++pBTModule)
|
||||
if( bt_name && MY_STRICMP(bt_name,pBTModule->nickname)==0 ) break;
|
||||
|
||||
for(pBTPostProcModule=BlobTrackPostProc_Modules; pBTPostProcModule->nickname; ++pBTPostProcModule)
|
||||
if( btpp_name && MY_STRICMP(btpp_name,pBTPostProcModule->nickname)==0 ) break;
|
||||
|
||||
for(pBTAnalysisModule=BlobTrackAnalysis_Modules; pBTAnalysisModule->nickname; ++pBTAnalysisModule)
|
||||
if( bta_name && MY_STRICMP(bta_name,pBTAnalysisModule->nickname)==0 ) break;
|
||||
|
||||
/* Create source video: */
|
||||
if(avi_name)
|
||||
pCap = cvCaptureFromFile(avi_name);
|
||||
|
||||
if(pCap==NULL)
|
||||
{
|
||||
printf("Can't open %s file\n",avi_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
{ /* Display parameters: */
|
||||
int i;
|
||||
FILE* log = log_name?fopen(log_name,"at"):NULL;
|
||||
if(log)
|
||||
{ /* Print to log file: */
|
||||
fprintf(log,"\n=== Blob Tracking pipline in processing mode===\n");
|
||||
if(avi_name)
|
||||
{
|
||||
fprintf(log,"AVIFile: %s\n",avi_name);
|
||||
}
|
||||
fprintf(log,"FGDetector: %s\n", pFGModule->nickname);
|
||||
fprintf(log,"BlobDetector: %s\n", pBDModule->nickname);
|
||||
fprintf(log,"BlobTracker: %s\n", pBTModule->nickname);
|
||||
fprintf(log,"BlobTrackPostProc: %s\n", pBTPostProcModule->nickname);
|
||||
fprintf(log,"BlobCorrection: %s\n", bt_corr);
|
||||
|
||||
fprintf(log,"Blob Trajectory Generator: %s (%s)\n",
|
||||
pBTGenModule?pBTGenModule->nickname:"None",
|
||||
track_name?track_name:"none");
|
||||
|
||||
fprintf(log,"BlobTrackAnalysis: %s\n", pBTAnalysisModule->nickname);
|
||||
fclose(log);
|
||||
}
|
||||
|
||||
printf("\n=== Blob Tracking pipline in %s mode===\n","processing");
|
||||
if(yml_name)
|
||||
{
|
||||
printf("ConfigFile: %s\n",yml_name);
|
||||
printf("BG: %s\n",yml_video_names[0]);
|
||||
printf("FG: ");
|
||||
for(i=1;i<(yml_video_num);++i){printf("%s",yml_video_names[i]);if((i+1)<yml_video_num)printf("|");};
|
||||
printf("\n");
|
||||
}
|
||||
if(avi_name)
|
||||
{
|
||||
printf("AVIFile: %s\n",avi_name);
|
||||
}
|
||||
printf("FGDetector: %s\n", pFGModule->nickname);
|
||||
printf("BlobDetector: %s\n", pBDModule->nickname);
|
||||
printf("BlobTracker: %s\n", pBTModule->nickname);
|
||||
printf("BlobTrackPostProc: %s\n", pBTPostProcModule->nickname);
|
||||
printf("BlobCorrection: %s\n", bt_corr);
|
||||
|
||||
printf("Blob Trajectory Generator: %s (%s)\n",
|
||||
pBTGenModule?pBTGenModule->nickname:"None",
|
||||
track_name?track_name:"none");
|
||||
|
||||
printf("BlobTrackAnalysis: %s\n", pBTAnalysisModule->nickname);
|
||||
|
||||
} /* Display parameters. */
|
||||
|
||||
{ /* Create autotracker module and its components: */
|
||||
param.FGTrainFrames = FGTrainFrames?atoi(FGTrainFrames):0;
|
||||
|
||||
/* Create FG Detection module: */
|
||||
param.pFG = pFGModule->create();
|
||||
if(!param.pFG)
|
||||
puts("Can not create FGDetector module");
|
||||
param.pFG->SetNickName(pFGModule->nickname);
|
||||
set_params(argc, argv, param.pFG, "fg", pFGModule->nickname);
|
||||
|
||||
/* Create Blob Entrance Detection module: */
|
||||
param.pBD = pBDModule->create();
|
||||
if(!param.pBD)
|
||||
puts("Can not create BlobDetector module");
|
||||
param.pBD->SetNickName(pBDModule->nickname);
|
||||
set_params(argc, argv, param.pBD, "bd", pBDModule->nickname);
|
||||
|
||||
/* Create blob tracker module: */
|
||||
param.pBT = pBTModule->create();
|
||||
if(!param.pBT)
|
||||
puts("Can not create BlobTracker module");
|
||||
param.pBT->SetNickName(pBTModule->nickname);
|
||||
set_params(argc, argv, param.pBT, "bt", pBTModule->nickname);
|
||||
|
||||
/* Create blob trajectory generation module: */
|
||||
param.pBTGen = NULL;
|
||||
if(pBTGenModule && track_name && pBTGenModule->create)
|
||||
{
|
||||
param.pBTGen = pBTGenModule->create();
|
||||
param.pBTGen->SetFileName(track_name);
|
||||
}
|
||||
if(param.pBTGen)
|
||||
{
|
||||
param.pBTGen->SetNickName(pBTGenModule->nickname);
|
||||
set_params(argc, argv, param.pBTGen, "btgen", pBTGenModule->nickname);
|
||||
}
|
||||
|
||||
/* Create blob trajectory post processing module: */
|
||||
param.pBTPP = NULL;
|
||||
if(pBTPostProcModule && pBTPostProcModule->create)
|
||||
{
|
||||
param.pBTPP = pBTPostProcModule->create();
|
||||
}
|
||||
if(param.pBTPP)
|
||||
{
|
||||
param.pBTPP->SetNickName(pBTPostProcModule->nickname);
|
||||
set_params(argc, argv, param.pBTPP, "btpp", pBTPostProcModule->nickname);
|
||||
}
|
||||
|
||||
param.UsePPData = (bt_corr && MY_STRICMP(bt_corr,"PostProcRes")==0);
|
||||
|
||||
/* Create blob trajectory analysis module: */
|
||||
param.pBTA = NULL;
|
||||
if(pBTAnalysisModule && pBTAnalysisModule->create)
|
||||
{
|
||||
param.pBTA = pBTAnalysisModule->create();
|
||||
param.pBTA->SetFileName(bta_data_name);
|
||||
}
|
||||
if(param.pBTA)
|
||||
{
|
||||
param.pBTA->SetNickName(pBTAnalysisModule->nickname);
|
||||
set_params(argc, argv, param.pBTA, "bta", pBTAnalysisModule->nickname);
|
||||
}
|
||||
|
||||
/* Create whole pipline: */
|
||||
pTracker = cvCreateBlobTrackerAuto1(¶m);
|
||||
if(!pTracker)
|
||||
puts("Can not create BlobTrackerAuto");
|
||||
}
|
||||
|
||||
{ /* Load states of each module from state file: */
|
||||
CvFileStorage* fs = NULL;
|
||||
if(loadstate_name)
|
||||
fs=cvOpenFileStorage(loadstate_name,NULL,CV_STORAGE_READ);
|
||||
if(fs)
|
||||
{
|
||||
printf("Load states for modules...\n");
|
||||
if(param.pBT)
|
||||
{
|
||||
CvFileNode* fn = cvGetFileNodeByName(fs,NULL,"BlobTracker");
|
||||
param.pBT->LoadState(fs,fn);
|
||||
}
|
||||
|
||||
if(param.pBTA)
|
||||
{
|
||||
CvFileNode* fn = cvGetFileNodeByName(fs,NULL,"BlobTrackAnalyser");
|
||||
param.pBTA->LoadState(fs,fn);
|
||||
}
|
||||
|
||||
if(pTracker)
|
||||
{
|
||||
CvFileNode* fn = cvGetFileNodeByName(fs,NULL,"BlobTrackerAuto");
|
||||
pTracker->LoadState(fs,fn);
|
||||
}
|
||||
|
||||
cvReleaseFileStorage(&fs);
|
||||
printf("... Modules states loaded\n");
|
||||
}
|
||||
} /* Load states of each module. */
|
||||
|
||||
{ /* Print module parameters: */
|
||||
struct DefMMM
|
||||
{
|
||||
CvVSModule* pM;
|
||||
const char* name;
|
||||
} Modules[] = {
|
||||
{(CvVSModule*)param.pFG,"FGdetector"},
|
||||
{(CvVSModule*)param.pBD,"BlobDetector"},
|
||||
{(CvVSModule*)param.pBT,"BlobTracker"},
|
||||
{(CvVSModule*)param.pBTGen,"TrackGen"},
|
||||
{(CvVSModule*)param.pBTPP,"PostProcessing"},
|
||||
{(CvVSModule*)param.pBTA,"TrackAnalysis"},
|
||||
{NULL,NULL}
|
||||
};
|
||||
int i;
|
||||
for(i=0; Modules[i].name; ++i)
|
||||
{
|
||||
if(Modules[i].pM)
|
||||
print_params(Modules[i].pM,Modules[i].name,log_name);
|
||||
}
|
||||
} /* Print module parameters. */
|
||||
|
||||
/* Run pipeline: */
|
||||
RunBlobTrackingAuto( pCap, pTracker, fgavi_name, btavi_name );
|
||||
|
||||
{ /* Save state and release modules: */
|
||||
CvFileStorage* fs = NULL;
|
||||
if(savestate_name)
|
||||
{
|
||||
fs=cvOpenFileStorage(savestate_name,NULL,CV_STORAGE_WRITE);
|
||||
}
|
||||
if(fs)
|
||||
{
|
||||
cvStartWriteStruct(fs,"BlobTracker",CV_NODE_MAP);
|
||||
if(param.pBT)param.pBT->SaveState(fs);
|
||||
cvEndWriteStruct(fs);
|
||||
cvStartWriteStruct(fs,"BlobTrackerAuto",CV_NODE_MAP);
|
||||
if(pTracker)pTracker->SaveState(fs);
|
||||
cvEndWriteStruct(fs);
|
||||
cvStartWriteStruct(fs,"BlobTrackAnalyser",CV_NODE_MAP);
|
||||
if(param.pBTA)param.pBTA->SaveState(fs);
|
||||
cvEndWriteStruct(fs);
|
||||
cvReleaseFileStorage(&fs);
|
||||
}
|
||||
if(param.pBT)cvReleaseBlobTracker(¶m.pBT);
|
||||
if(param.pBD)cvReleaseBlobDetector(¶m.pBD);
|
||||
if(param.pBTGen)cvReleaseBlobTrackGen(¶m.pBTGen);
|
||||
if(param.pBTA)cvReleaseBlobTrackAnalysis(¶m.pBTA);
|
||||
if(param.pFG)cvReleaseFGDetector(¶m.pFG);
|
||||
if(pTracker)cvReleaseBlobTrackerAuto(&pTracker);
|
||||
|
||||
} /* Save state and release modules. */
|
||||
|
||||
if(pCap)
|
||||
cvReleaseCapture(&pCap);
|
||||
|
||||
return 0;
|
||||
|
||||
} /* main() */
|
||||
@@ -1,16 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ $# -gt 0 ] ; then
|
||||
base=`basename $1 .c`
|
||||
echo "compiling $base"
|
||||
gcc -ggdb `pkg-config opencv --cflags --libs` $base.c -o $base
|
||||
else
|
||||
for i in *.c; do
|
||||
echo "compiling $i"
|
||||
gcc -ggdb `pkg-config --cflags opencv` -o `basename $i .c` $i `pkg-config --libs opencv`;
|
||||
done
|
||||
for i in *.cpp; do
|
||||
echo "compiling $i"
|
||||
g++ -ggdb `pkg-config --cflags opencv` -o `basename $i .cpp` $i `pkg-config --libs opencv`;
|
||||
done
|
||||
fi
|
||||
@@ -1,10 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<opencv_storage>
|
||||
<numTrees>20</numTrees>
|
||||
<depth>7</depth>
|
||||
<views>1000</views>
|
||||
<patchSize>20</patchSize>
|
||||
<reducedNumDim>30</reducedNumDim>
|
||||
<numQuantBits>4</numQuantBits>
|
||||
<printStatus>1</printStatus>
|
||||
</opencv_storage>
|
||||
|
Before Width: | Height: | Size: 64 KiB |
@@ -1,167 +0,0 @@
|
||||
#include "opencv2/imgproc/imgproc_c.h"
|
||||
#include "opencv2/highgui/highgui_c.h"
|
||||
#include <stdio.h>
|
||||
|
||||
static void help(void)
|
||||
{
|
||||
printf("\nThis program creates an image to demonstrate the use of the \"c\" contour\n"
|
||||
"functions: cvFindContours() and cvApproxPoly() along with the storage\n"
|
||||
"functions cvCreateMemStorage() and cvDrawContours().\n"
|
||||
"It also shows the use of a trackbar to control contour retrieval.\n"
|
||||
"\n"
|
||||
"Usage :\n"
|
||||
"./contours\n");
|
||||
}
|
||||
|
||||
#define w 500
|
||||
int levels = 3;
|
||||
CvSeq* contours = 0;
|
||||
|
||||
static void on_trackbar(int pos)
|
||||
{
|
||||
IplImage* cnt_img = cvCreateImage( cvSize(w,w), 8, 3 );
|
||||
CvSeq* _contours = contours;
|
||||
int _levels = levels - 3;
|
||||
(void)pos;
|
||||
|
||||
if( _levels <= 0 ) // get to the nearest face to make it look more funny
|
||||
_contours = _contours->h_next->h_next->h_next;
|
||||
cvZero( cnt_img );
|
||||
cvDrawContours( cnt_img, _contours, CV_RGB(255,0,0), CV_RGB(0,255,0), _levels, 3, CV_AA, cvPoint(0,0) );
|
||||
cvShowImage( "contours", cnt_img );
|
||||
cvReleaseImage( &cnt_img );
|
||||
}
|
||||
|
||||
static void findCComp( IplImage* img )
|
||||
{
|
||||
int x, y, cidx = 1;
|
||||
IplImage* mask = cvCreateImage( cvSize(img->width+2, img->height+2), 8, 1 );
|
||||
cvZero(mask);
|
||||
cvRectangle( mask, cvPoint(0, 0), cvPoint(mask->width-1, mask->height-1),
|
||||
cvScalarAll(1), 1, 8, 0 );
|
||||
|
||||
for( y = 0; y < img->height; y++ )
|
||||
for( x = 0; x < img->width; x++ )
|
||||
{
|
||||
if( CV_IMAGE_ELEM(mask, uchar, y+1, x+1) != 0 )
|
||||
continue;
|
||||
cvFloodFill(img, cvPoint(x,y), cvScalarAll(cidx),
|
||||
cvScalarAll(0), cvScalarAll(0), 0, 4, mask);
|
||||
cidx++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int i, j;
|
||||
CvMemStorage* storage = cvCreateMemStorage(0);
|
||||
IplImage* img = cvCreateImage( cvSize(w,w), 8, 1 );
|
||||
IplImage* img32f = cvCreateImage( cvSize(w,w), IPL_DEPTH_32F, 1 );
|
||||
IplImage* img32s = cvCreateImage( cvSize(w,w), IPL_DEPTH_32S, 1 );
|
||||
IplImage* img3 = cvCreateImage( cvSize(w,w), 8, 3 );
|
||||
(void)argc; (void)argv;
|
||||
|
||||
help();
|
||||
cvZero( img );
|
||||
|
||||
for( i=0; i < 6; i++ )
|
||||
{
|
||||
int dx = (i%2)*250 - 30;
|
||||
int dy = (i/2)*150;
|
||||
CvScalar white = cvRealScalar(255);
|
||||
CvScalar black = cvRealScalar(0);
|
||||
|
||||
if( i == 0 )
|
||||
{
|
||||
for( j = 0; j <= 10; j++ )
|
||||
{
|
||||
double angle = (j+5)*CV_PI/21;
|
||||
cvLine(img, cvPoint(cvRound(dx+100+j*10-80*cos(angle)),
|
||||
cvRound(dy+100-90*sin(angle))),
|
||||
cvPoint(cvRound(dx+100+j*10-30*cos(angle)),
|
||||
cvRound(dy+100-30*sin(angle))), white, 3, 8, 0);
|
||||
}
|
||||
}
|
||||
|
||||
cvEllipse( img, cvPoint(dx+150, dy+100), cvSize(100,70), 0, 0, 360, white, -1, 8, 0 );
|
||||
cvEllipse( img, cvPoint(dx+115, dy+70), cvSize(30,20), 0, 0, 360, black, -1, 8, 0 );
|
||||
cvEllipse( img, cvPoint(dx+185, dy+70), cvSize(30,20), 0, 0, 360, black, -1, 8, 0 );
|
||||
cvEllipse( img, cvPoint(dx+115, dy+70), cvSize(15,15), 0, 0, 360, white, -1, 8, 0 );
|
||||
cvEllipse( img, cvPoint(dx+185, dy+70), cvSize(15,15), 0, 0, 360, white, -1, 8, 0 );
|
||||
cvEllipse( img, cvPoint(dx+115, dy+70), cvSize(5,5), 0, 0, 360, black, -1, 8, 0 );
|
||||
cvEllipse( img, cvPoint(dx+185, dy+70), cvSize(5,5), 0, 0, 360, black, -1, 8, 0 );
|
||||
cvEllipse( img, cvPoint(dx+150, dy+100), cvSize(10,5), 0, 0, 360, black, -1, 8, 0 );
|
||||
cvEllipse( img, cvPoint(dx+150, dy+150), cvSize(40,10), 0, 0, 360, black, -1, 8, 0 );
|
||||
cvEllipse( img, cvPoint(dx+27, dy+100), cvSize(20,35), 0, 0, 360, white, -1, 8, 0 );
|
||||
cvEllipse( img, cvPoint(dx+273, dy+100), cvSize(20,35), 0, 0, 360, white, -1, 8, 0 );
|
||||
}
|
||||
|
||||
cvNamedWindow( "image", 1 );
|
||||
cvShowImage( "image", img );
|
||||
cvConvert( img, img32f );
|
||||
findCComp( img32f );
|
||||
cvConvert( img32f, img32s );
|
||||
|
||||
cvFindContours( img32s, storage, &contours, sizeof(CvContour),
|
||||
CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0) );
|
||||
|
||||
//cvFindContours( img, storage, &contours, sizeof(CvContour),
|
||||
// CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0) );
|
||||
|
||||
|
||||
{
|
||||
const char* attrs[] = {"recursive", "1", 0};
|
||||
cvSave("contours.xml", contours, 0, 0, cvAttrList(attrs, 0));
|
||||
contours = (CvSeq*)cvLoad("contours.xml", storage, 0, 0);
|
||||
}
|
||||
|
||||
// comment this out if you do not want approximation
|
||||
contours = cvApproxPoly( contours, sizeof(CvContour), storage, CV_POLY_APPROX_DP, 3, 1 );
|
||||
|
||||
cvNamedWindow( "contours", 1 );
|
||||
cvCreateTrackbar( "levels+3", "contours", &levels, 7, on_trackbar );
|
||||
|
||||
{
|
||||
CvRNG rng = cvRNG(-1);
|
||||
|
||||
CvSeq* tcontours = contours;
|
||||
cvCvtColor( img, img3, CV_GRAY2BGR );
|
||||
while( tcontours->h_next )
|
||||
tcontours = tcontours->h_next;
|
||||
|
||||
for( ; tcontours != 0; tcontours = tcontours->h_prev )
|
||||
{
|
||||
CvScalar color;
|
||||
color.val[0] = cvRandInt(&rng) % 256;
|
||||
color.val[1] = cvRandInt(&rng) % 256;
|
||||
color.val[2] = cvRandInt(&rng) % 256;
|
||||
color.val[3] = cvRandInt(&rng) % 256;
|
||||
cvDrawContours(img3, tcontours, color, color, 0, -1, 8, cvPoint(0,0));
|
||||
if( tcontours->v_next )
|
||||
{
|
||||
color.val[0] = cvRandInt(&rng) % 256;
|
||||
color.val[1] = cvRandInt(&rng) % 256;
|
||||
color.val[2] = cvRandInt(&rng) % 256;
|
||||
color.val[3] = cvRandInt(&rng) % 256;
|
||||
cvDrawContours(img3, tcontours->v_next, color, color, 1, -1, 8, cvPoint(0,0));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
cvShowImage( "colored", img3 );
|
||||
on_trackbar(0);
|
||||
cvWaitKey(0);
|
||||
cvReleaseMemStorage( &storage );
|
||||
cvReleaseImage( &img );
|
||||
cvReleaseImage( &img32f );
|
||||
cvReleaseImage( &img32s );
|
||||
cvReleaseImage( &img3 );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef _EiC
|
||||
main(1,"");
|
||||
#endif
|
||||
@@ -1,50 +0,0 @@
|
||||
#include "opencv2/objdetect/objdetect_c.h"
|
||||
#include "opencv2/highgui/highgui_c.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static void help(void)
|
||||
{
|
||||
printf("\n This sample demonstrates cascade's convertation \n"
|
||||
"Usage:\n"
|
||||
"./convert_cascade --size=\"<width>x<height>\"<convertation size> \n"
|
||||
" input_cascade_path \n"
|
||||
" output_cascade_filename\n"
|
||||
"Example: \n"
|
||||
"./convert_cascade --size=640x480 ../../opencv/data/haarcascades/haarcascade_eye.xml ../../opencv/data/haarcascades/test_cascade.xml \n"
|
||||
);
|
||||
}
|
||||
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
const char* size_opt = "--size=";
|
||||
char comment[1024];
|
||||
CvHaarClassifierCascade* cascade = 0;
|
||||
CvSize size;
|
||||
|
||||
help();
|
||||
|
||||
if( argc != 4 || strncmp( argv[1], size_opt, strlen(size_opt) ) != 0 )
|
||||
{
|
||||
help();
|
||||
return -1;
|
||||
}
|
||||
|
||||
sscanf( argv[1], "--size=%ux%u", &size.width, &size.height );
|
||||
cascade = cvLoadHaarClassifierCascade( argv[2], size );
|
||||
|
||||
if( !cascade )
|
||||
{
|
||||
fprintf( stderr, "Input cascade could not be found/opened\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
sprintf( comment, "Automatically converted from %s, window size = %dx%d", argv[2], size.width, size.height );
|
||||
cvSave( argv[3], cascade, 0, comment, cvAttrList(0,0) );
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef _EiC
|
||||
main(1,"facedetect.c");
|
||||
#endif
|
||||
@@ -1,92 +0,0 @@
|
||||
# Microsoft Developer Studio Project File - Name="cvsample" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Console Application" 0x0103
|
||||
|
||||
CFG=cvsample - Win32 Release
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "cvsample.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "cvsample.mak" CFG="cvsample - Win32 Release"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "cvsample - Win32 Release" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE "cvsample - Win32 Debug" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "cvsample - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "..\..\_temp\cvsample_Release"
|
||||
# PROP Intermediate_Dir "..\..\_temp\cvsample_Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
F90=df.exe
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /MD /W4 /Gm /GX /Zi /O2 /I "../../cxcore/include" /I "../../cv/include" /I "../../otherlibs/highgui" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib cxcore.lib cv.lib highgui.lib /nologo /subsystem:console /debug /machine:I386 /nodefaultlib:"libmmd.lib" /out:".\cvsample.exe" /libpath:"../../lib"
|
||||
|
||||
!ELSEIF "$(CFG)" == "cvsample - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "..\..\_temp\cvsample_Debug"
|
||||
# PROP Intermediate_Dir "..\..\_temp\cvsample_Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
F90=df.exe
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W4 /Gm /GX /Zi /Od /I "../../cxcore/include" /I "../../cv/include" /I "../../otherlibs/highgui" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib cxcored.lib cvd.lib highguid.lib /nologo /subsystem:console /debug /machine:I386 /nodefaultlib:"libmmdd.lib" /out:".\cvsampled.exe" /pdbtype:sept /libpath:"../../lib"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "cvsample - Win32 Release"
|
||||
# Name "cvsample - Win32 Debug"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\squares.c
|
||||
# End Source File
|
||||
# End Target
|
||||
# End Project
|
||||
@@ -1,413 +0,0 @@
|
||||
<?xml version="1.0" encoding="windows-1251"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8,00"
|
||||
Name="cvsample"
|
||||
ProjectGUID="{2820F96A-13D2-4EFE-BC9F-A9AF482026AE}"
|
||||
RootNamespace="cvsample"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
<Platform
|
||||
Name="x64"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="$(TEMP)\opencv.build\$(ProjectName)_$(ConfigurationName).$(PlatformName)"
|
||||
IntermediateDirectory="$(OutDir)"
|
||||
ConfigurationType="1"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TypeLibraryName=".\..\..\_temp\cvsample_Dbg/cvsample.tlb"
|
||||
HeaderFileName=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../cxcore/include,../../cv/include,../../otherlibs/highgui"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
PrecompiledHeaderFile=".\..\..\_temp\cvsample_Dbg/cvsample.pch"
|
||||
AssemblerListingLocation="$(IntDir)\"
|
||||
ObjectFile="$(IntDir)\"
|
||||
ProgramDataBaseFileName="$(IntDir)\"
|
||||
WarningLevel="4"
|
||||
SuppressStartupBanner="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="1033"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib cxcored.lib cvd.lib highguid.lib"
|
||||
OutputFile=".\cvsampled.exe"
|
||||
LinkIncremental="2"
|
||||
SuppressStartupBanner="true"
|
||||
AdditionalLibraryDirectories="../../lib"
|
||||
IgnoreDefaultLibraryNames="libmmdd.lib"
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="$(IntDir)/$(ProjectName)d.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile="$(IntDir)\$(ProjectName).bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Debug|x64"
|
||||
OutputDirectory="$(TEMP)\opencv.build\$(ProjectName)_$(ConfigurationName).$(PlatformName)"
|
||||
IntermediateDirectory="$(OutDir)"
|
||||
ConfigurationType="1"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
TypeLibraryName=".\..\..\_temp\cvsample_Dbg64/cvsample.tlb"
|
||||
HeaderFileName=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../cxcore/include,../../cv/include,../../otherlibs/highgui"
|
||||
PreprocessorDefinitions="WIN32;WIN64;EM64T;_DEBUG;_CONSOLE"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
PrecompiledHeaderFile=".\..\..\_temp\cvsample_Dbg64/cvsample.pch"
|
||||
AssemblerListingLocation="$(IntDir)\"
|
||||
ObjectFile="$(IntDir)\"
|
||||
ProgramDataBaseFileName="$(IntDir)\"
|
||||
WarningLevel="4"
|
||||
SuppressStartupBanner="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="1033"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib cxcored_64.lib cvd_64.lib highguid_64.lib"
|
||||
OutputFile=".\cvsampled_64.exe"
|
||||
LinkIncremental="2"
|
||||
SuppressStartupBanner="true"
|
||||
AdditionalLibraryDirectories="../../lib"
|
||||
IgnoreDefaultLibraryNames="libmmdd.lib"
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="$(IntDir)/$(ProjectName)d_64.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile="$(IntDir)\$(ProjectName).bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(TEMP)\opencv.build\$(ProjectName)_$(ConfigurationName).$(PlatformName)"
|
||||
IntermediateDirectory="$(OutDir)"
|
||||
ConfigurationType="1"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TypeLibraryName=".\..\..\_temp\cvsample_Rls/cvsample.tlb"
|
||||
HeaderFileName=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="1"
|
||||
AdditionalIncludeDirectories="../../cxcore/include,../../cv/include,../../otherlibs/highgui"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
StringPooling="true"
|
||||
MinimalRebuild="true"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="true"
|
||||
PrecompiledHeaderFile=".\..\..\_temp\cvsample_Rls/cvsample.pch"
|
||||
AssemblerListingLocation="$(IntDir)\"
|
||||
ObjectFile="$(IntDir)\"
|
||||
ProgramDataBaseFileName="$(IntDir)\"
|
||||
WarningLevel="4"
|
||||
SuppressStartupBanner="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="1033"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib cxcore.lib cv.lib highgui.lib"
|
||||
OutputFile=".\cvsample.exe"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
AdditionalLibraryDirectories="../../lib"
|
||||
IgnoreDefaultLibraryNames="libmmd.lib"
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="$(IntDir)/$(ProjectName).pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile="$(IntDir)\$(ProjectName).bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|x64"
|
||||
OutputDirectory="$(TEMP)\opencv.build\$(ProjectName)_$(ConfigurationName).$(PlatformName)"
|
||||
IntermediateDirectory="$(OutDir)"
|
||||
ConfigurationType="1"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
TypeLibraryName=".\..\..\_temp\cvsample_Rls64/cvsample.tlb"
|
||||
HeaderFileName=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="1"
|
||||
AdditionalIncludeDirectories="../../cxcore/include,../../cv/include,../../otherlibs/highgui"
|
||||
PreprocessorDefinitions="WIN32;WIN64;EM64T;NDEBUG;_CONSOLE"
|
||||
StringPooling="true"
|
||||
MinimalRebuild="true"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="true"
|
||||
PrecompiledHeaderFile=".\..\..\_temp\cvsample_Rls64/cvsample.pch"
|
||||
AssemblerListingLocation="$(IntDir)\"
|
||||
ObjectFile="$(IntDir)\"
|
||||
ProgramDataBaseFileName="$(IntDir)\"
|
||||
WarningLevel="4"
|
||||
SuppressStartupBanner="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="1033"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib cxcore_64.lib cv_64.lib highgui_64.lib"
|
||||
OutputFile=".\cvsample_64.exe"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
AdditionalLibraryDirectories="../../lib"
|
||||
IgnoreDefaultLibraryNames="libmmd.lib"
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="$(IntDir)/$(ProjectName)_64.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile="$(IntDir)\$(ProjectName).bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<File
|
||||
RelativePath=".\stereo_calib.cpp"
|
||||
>
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
@@ -1,242 +0,0 @@
|
||||
#include <opencv2/imgproc/imgproc_c.h>
|
||||
#include <opencv2/highgui/highgui_c.h>
|
||||
#include <opencv2/legacy.hpp>
|
||||
|
||||
#include <stdio.h>
|
||||
static void help( void )
|
||||
{
|
||||
printf("\nThis program demostrates iterative construction of\n"
|
||||
"delaunay triangulation and voronoi tesselation.\n"
|
||||
"It draws a random set of points in an image and then delaunay triangulates them.\n"
|
||||
"Usage: \n"
|
||||
"./delaunay \n"
|
||||
"\nThis program builds the traingulation interactively, you may stop this process by\n"
|
||||
"hitting any key.\n");
|
||||
}
|
||||
|
||||
static CvSubdiv2D* init_delaunay( CvMemStorage* storage,
|
||||
CvRect rect )
|
||||
{
|
||||
CvSubdiv2D* subdiv;
|
||||
|
||||
subdiv = cvCreateSubdiv2D( CV_SEQ_KIND_SUBDIV2D, sizeof(*subdiv),
|
||||
sizeof(CvSubdiv2DPoint),
|
||||
sizeof(CvQuadEdge2D),
|
||||
storage );
|
||||
cvInitSubdivDelaunay2D( subdiv, rect );
|
||||
|
||||
return subdiv;
|
||||
}
|
||||
|
||||
|
||||
static void draw_subdiv_point( IplImage* img, CvPoint2D32f fp, CvScalar color )
|
||||
{
|
||||
cvCircle( img, cvPoint(cvRound(fp.x), cvRound(fp.y)), 3, color, CV_FILLED, 8, 0 );
|
||||
}
|
||||
|
||||
|
||||
static void draw_subdiv_edge( IplImage* img, CvSubdiv2DEdge edge, CvScalar color )
|
||||
{
|
||||
CvSubdiv2DPoint* org_pt;
|
||||
CvSubdiv2DPoint* dst_pt;
|
||||
CvPoint2D32f org;
|
||||
CvPoint2D32f dst;
|
||||
CvPoint iorg, idst;
|
||||
|
||||
org_pt = cvSubdiv2DEdgeOrg(edge);
|
||||
dst_pt = cvSubdiv2DEdgeDst(edge);
|
||||
|
||||
if( org_pt && dst_pt )
|
||||
{
|
||||
org = org_pt->pt;
|
||||
dst = dst_pt->pt;
|
||||
|
||||
iorg = cvPoint( cvRound( org.x ), cvRound( org.y ));
|
||||
idst = cvPoint( cvRound( dst.x ), cvRound( dst.y ));
|
||||
|
||||
cvLine( img, iorg, idst, color, 1, CV_AA, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void draw_subdiv( IplImage* img, CvSubdiv2D* subdiv,
|
||||
CvScalar delaunay_color, CvScalar voronoi_color )
|
||||
{
|
||||
CvSeqReader reader;
|
||||
int i, total = subdiv->edges->total;
|
||||
int elem_size = subdiv->edges->elem_size;
|
||||
|
||||
cvStartReadSeq( (CvSeq*)(subdiv->edges), &reader, 0 );
|
||||
|
||||
for( i = 0; i < total; i++ )
|
||||
{
|
||||
CvQuadEdge2D* edge = (CvQuadEdge2D*)(reader.ptr);
|
||||
|
||||
if( CV_IS_SET_ELEM( edge ))
|
||||
{
|
||||
draw_subdiv_edge( img, (CvSubdiv2DEdge)edge + 1, voronoi_color );
|
||||
draw_subdiv_edge( img, (CvSubdiv2DEdge)edge, delaunay_color );
|
||||
}
|
||||
|
||||
CV_NEXT_SEQ_ELEM( elem_size, reader );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void locate_point( CvSubdiv2D* subdiv, CvPoint2D32f fp, IplImage* img,
|
||||
CvScalar active_color )
|
||||
{
|
||||
CvSubdiv2DEdge e;
|
||||
CvSubdiv2DEdge e0 = 0;
|
||||
CvSubdiv2DPoint* p = 0;
|
||||
|
||||
cvSubdiv2DLocate( subdiv, fp, &e0, &p );
|
||||
|
||||
if( e0 )
|
||||
{
|
||||
e = e0;
|
||||
do
|
||||
{
|
||||
draw_subdiv_edge( img, e, active_color );
|
||||
e = cvSubdiv2DGetEdge(e,CV_NEXT_AROUND_LEFT);
|
||||
}
|
||||
while( e != e0 );
|
||||
}
|
||||
|
||||
draw_subdiv_point( img, fp, active_color );
|
||||
}
|
||||
|
||||
|
||||
static void draw_subdiv_facet( IplImage* img, CvSubdiv2DEdge edge )
|
||||
{
|
||||
CvSubdiv2DEdge t = edge;
|
||||
int i, count = 0;
|
||||
CvPoint* buf = 0;
|
||||
|
||||
// count number of edges in facet
|
||||
do
|
||||
{
|
||||
count++;
|
||||
t = cvSubdiv2DGetEdge( t, CV_NEXT_AROUND_LEFT );
|
||||
} while (t != edge );
|
||||
|
||||
buf = (CvPoint*)malloc( count * sizeof(buf[0]));
|
||||
|
||||
// gather points
|
||||
t = edge;
|
||||
for( i = 0; i < count; i++ )
|
||||
{
|
||||
CvSubdiv2DPoint* pt = cvSubdiv2DEdgeOrg( t );
|
||||
if( !pt ) break;
|
||||
buf[i] = cvPoint( cvRound(pt->pt.x), cvRound(pt->pt.y));
|
||||
t = cvSubdiv2DGetEdge( t, CV_NEXT_AROUND_LEFT );
|
||||
}
|
||||
|
||||
if( i == count )
|
||||
{
|
||||
CvSubdiv2DPoint* pt = cvSubdiv2DEdgeDst( cvSubdiv2DRotateEdge( edge, 1 ));
|
||||
cvFillConvexPoly( img, buf, count, CV_RGB(rand()&255,rand()&255,rand()&255), CV_AA, 0 );
|
||||
cvPolyLine( img, &buf, &count, 1, 1, CV_RGB(0,0,0), 1, CV_AA, 0);
|
||||
draw_subdiv_point( img, pt->pt, CV_RGB(0,0,0));
|
||||
}
|
||||
free( buf );
|
||||
}
|
||||
|
||||
static void paint_voronoi( CvSubdiv2D* subdiv, IplImage* img )
|
||||
{
|
||||
CvSeqReader reader;
|
||||
int i, total = subdiv->edges->total;
|
||||
int elem_size = subdiv->edges->elem_size;
|
||||
|
||||
cvCalcSubdivVoronoi2D( subdiv );
|
||||
|
||||
cvStartReadSeq( (CvSeq*)(subdiv->edges), &reader, 0 );
|
||||
|
||||
for( i = 0; i < total; i++ )
|
||||
{
|
||||
CvQuadEdge2D* edge = (CvQuadEdge2D*)(reader.ptr);
|
||||
|
||||
if( CV_IS_SET_ELEM( edge ))
|
||||
{
|
||||
CvSubdiv2DEdge e = (CvSubdiv2DEdge)edge;
|
||||
// left
|
||||
draw_subdiv_facet( img, cvSubdiv2DRotateEdge( e, 1 ));
|
||||
|
||||
// right
|
||||
draw_subdiv_facet( img, cvSubdiv2DRotateEdge( e, 3 ));
|
||||
}
|
||||
|
||||
CV_NEXT_SEQ_ELEM( elem_size, reader );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void run(void)
|
||||
{
|
||||
char win[] = "source";
|
||||
int i;
|
||||
CvRect rect = { 0, 0, 600, 600 };
|
||||
CvMemStorage* storage;
|
||||
CvSubdiv2D* subdiv;
|
||||
IplImage* img;
|
||||
CvScalar active_facet_color, delaunay_color, voronoi_color, bkgnd_color;
|
||||
|
||||
active_facet_color = CV_RGB( 255, 0, 0 );
|
||||
delaunay_color = CV_RGB( 0,0,0);
|
||||
voronoi_color = CV_RGB(0, 180, 0);
|
||||
bkgnd_color = CV_RGB(255,255,255);
|
||||
|
||||
img = cvCreateImage( cvSize(rect.width,rect.height), 8, 3 );
|
||||
cvSet( img, bkgnd_color, 0 );
|
||||
|
||||
cvNamedWindow( win, 1 );
|
||||
|
||||
storage = cvCreateMemStorage(0);
|
||||
subdiv = init_delaunay( storage, rect );
|
||||
|
||||
printf("Delaunay triangulation will be build now interactively.\n"
|
||||
"To stop the process, press any key\n\n");
|
||||
|
||||
for( i = 0; i < 200; i++ )
|
||||
{
|
||||
CvPoint2D32f fp = cvPoint2D32f( (float)(rand()%(rect.width-10)+5),
|
||||
(float)(rand()%(rect.height-10)+5));
|
||||
|
||||
locate_point( subdiv, fp, img, active_facet_color );
|
||||
cvShowImage( win, img );
|
||||
|
||||
if( cvWaitKey( 100 ) >= 0 )
|
||||
break;
|
||||
|
||||
cvSubdivDelaunay2DInsert( subdiv, fp );
|
||||
cvCalcSubdivVoronoi2D( subdiv );
|
||||
cvSet( img, bkgnd_color, 0 );
|
||||
draw_subdiv( img, subdiv, delaunay_color, voronoi_color );
|
||||
cvShowImage( win, img );
|
||||
|
||||
if( cvWaitKey( 100 ) >= 0 )
|
||||
break;
|
||||
}
|
||||
|
||||
cvSet( img, bkgnd_color, 0 );
|
||||
paint_voronoi( subdiv, img );
|
||||
cvShowImage( win, img );
|
||||
|
||||
cvWaitKey(0);
|
||||
|
||||
cvReleaseMemStorage( &storage );
|
||||
cvReleaseImage(&img);
|
||||
cvDestroyWindow( win );
|
||||
}
|
||||
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
(void)argc; (void)argv;
|
||||
help();
|
||||
run();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef _EiC
|
||||
main( 1, "delaunay.c" );
|
||||
#endif
|
||||
@@ -1,15 +0,0 @@
|
||||
PROJECT(opencv_example)
|
||||
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
|
||||
if(COMMAND cmake_policy)
|
||||
cmake_policy(SET CMP0003 NEW)
|
||||
endif(COMMAND cmake_policy)
|
||||
|
||||
FIND_PACKAGE( OpenCV REQUIRED )
|
||||
|
||||
# Declare the target (an executable)
|
||||
ADD_EXECUTABLE(opencv_example minarea.c)
|
||||
|
||||
TARGET_LINK_LIBRARIES(opencv_example ${OpenCV_LIBS})
|
||||
|
||||
#MESSAGE(STATUS "OpenCV_LIBS: ${OpenCV_LIBS}")
|
||||
@@ -1,27 +0,0 @@
|
||||
Example for CMake build system.
|
||||
|
||||
Compile OpenCV with cmake, preferently in an off-tree build, for example:
|
||||
|
||||
$ mkdir opencv-release
|
||||
$ cd opencv-release
|
||||
$ cmake <OPENCV_SRC_PATH>
|
||||
$ make
|
||||
|
||||
And, *only optionally*, install it with.
|
||||
$ sudo make install
|
||||
|
||||
Then create the binary directory for the example with:
|
||||
$ mkdir example-release
|
||||
$ cd example-release
|
||||
|
||||
Then, if "make install" have been executed, directly running
|
||||
$ cmake <OPENCV_SRC_PATH>/samples/c/example_cmake/
|
||||
|
||||
will detect the "OpenCVConfig.cmake" file and the project is ready to compile.
|
||||
|
||||
If "make install" has not been executed, you'll have to manually pick the opencv
|
||||
binary directory (Under Windows CMake may remember the correct directory). Open
|
||||
the CMake gui with:
|
||||
$ cmake-gui <OPENCV_SRC_PATH>/samples/c/example_cmake/
|
||||
|
||||
And pick the correct value for OpenCV_DIR.
|
||||
@@ -1,116 +0,0 @@
|
||||
#ifdef _CH_
|
||||
#pragma package <opencv>
|
||||
#endif
|
||||
|
||||
#ifndef _EiC
|
||||
#include "cv.h"
|
||||
#include "highgui.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#define ARRAY 1
|
||||
|
||||
void help()
|
||||
{
|
||||
printf("\nThis program demonstrates finding the minimum enclosing box or circle of a set\n"
|
||||
"of points using functions: minAreaRect() minEnclosingCircle().\n"
|
||||
"Random points are generated and then enclosed.\n"
|
||||
"Call:\n"
|
||||
"./minarea\n");
|
||||
}
|
||||
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
IplImage* img = cvCreateImage( cvSize( 500, 500 ), 8, 3 );
|
||||
#if !ARRAY
|
||||
CvMemStorage* storage = cvCreateMemStorage(0);
|
||||
#endif
|
||||
help();
|
||||
cvNamedWindow( "rect & circle", 1 );
|
||||
|
||||
for(;;)
|
||||
{
|
||||
char key;
|
||||
int i, count = rand()%100 + 1;
|
||||
CvPoint pt0, pt;
|
||||
CvBox2D box;
|
||||
CvPoint2D32f box_vtx[4];
|
||||
CvPoint2D32f center;
|
||||
CvPoint icenter;
|
||||
float radius;
|
||||
#if !ARRAY
|
||||
CvSeq* ptseq = cvCreateSeq( CV_SEQ_KIND_GENERIC|CV_32SC2, sizeof(CvContour),
|
||||
sizeof(CvPoint), storage );
|
||||
for( i = 0; i < count; i++ )
|
||||
{
|
||||
pt0.x = rand() % (img->width/2) + img->width/4;
|
||||
pt0.y = rand() % (img->height/2) + img->height/4;
|
||||
cvSeqPush( ptseq, &pt0 );
|
||||
}
|
||||
#ifndef _EiC /* unfortunately, here EiC crashes */
|
||||
box = cvMinAreaRect2( ptseq, 0 );
|
||||
#endif
|
||||
cvMinEnclosingCircle( ptseq, ¢er, &radius );
|
||||
#else
|
||||
CvPoint* points = (CvPoint*)malloc( count * sizeof(points[0]));
|
||||
CvMat pointMat = cvMat( 1, count, CV_32SC2, points );
|
||||
|
||||
for( i = 0; i < count; i++ )
|
||||
{
|
||||
pt0.x = rand() % (img->width/2) + img->width/4;
|
||||
pt0.y = rand() % (img->height/2) + img->height/4;
|
||||
points[i] = pt0;
|
||||
}
|
||||
#ifndef _EiC
|
||||
box = cvMinAreaRect2( &pointMat, 0 );
|
||||
#endif
|
||||
cvMinEnclosingCircle( &pointMat, ¢er, &radius );
|
||||
#endif
|
||||
cvBoxPoints( box, box_vtx );
|
||||
cvZero( img );
|
||||
for( i = 0; i < count; i++ )
|
||||
{
|
||||
#if !ARRAY
|
||||
pt0 = *CV_GET_SEQ_ELEM( CvPoint, ptseq, i );
|
||||
#else
|
||||
pt0 = points[i];
|
||||
#endif
|
||||
cvCircle( img, pt0, 2, CV_RGB( 255, 0, 0 ), CV_FILLED, CV_AA, 0 );
|
||||
}
|
||||
|
||||
#ifndef _EiC
|
||||
pt0.x = cvRound(box_vtx[3].x);
|
||||
pt0.y = cvRound(box_vtx[3].y);
|
||||
for( i = 0; i < 4; i++ )
|
||||
{
|
||||
pt.x = cvRound(box_vtx[i].x);
|
||||
pt.y = cvRound(box_vtx[i].y);
|
||||
cvLine(img, pt0, pt, CV_RGB(0, 255, 0), 1, CV_AA, 0);
|
||||
pt0 = pt;
|
||||
}
|
||||
#endif
|
||||
icenter.x = cvRound(center.x);
|
||||
icenter.y = cvRound(center.y);
|
||||
cvCircle( img, icenter, cvRound(radius), CV_RGB(255, 255, 0), 1, CV_AA, 0 );
|
||||
|
||||
cvShowImage( "rect & circle", img );
|
||||
|
||||
key = (char) cvWaitKey(0);
|
||||
if( key == 27 || key == 'q' || key == 'Q' ) // 'ESC'
|
||||
break;
|
||||
|
||||
#if !ARRAY
|
||||
cvClearMemStorage( storage );
|
||||
#else
|
||||
free( points );
|
||||
#endif
|
||||
}
|
||||
|
||||
cvDestroyWindow( "rect & circle" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef _EiC
|
||||
main(1,"convexhull.c");
|
||||
#endif
|
||||
@@ -1,2 +0,0 @@
|
||||
REM an example of using haar cascade recognition for face and eye detection.
|
||||
facedetect --cascade="../../data/haarcascades/haarcascade_frontalface_alt.xml" --nested-cascade="../../data/haarcascades/haarcascade_eye.xml" --scale=1.3 %1
|
||||
@@ -1,75 +0,0 @@
|
||||
#include "opencv2/video/tracking_c.h"
|
||||
#include "opencv2/highgui/highgui_c.h"
|
||||
#include "opencv2/imgproc/imgproc_c.h"
|
||||
#include <stdio.h>
|
||||
|
||||
static void help(void)
|
||||
{
|
||||
printf(
|
||||
"\n This program demonstrate dense \"Farneback\n optical flow\n"
|
||||
"It read from camera 0, and shows how to use and display dense Franeback optical flow\n"
|
||||
"Usage: \n"
|
||||
"./fback_c \n");
|
||||
|
||||
}
|
||||
|
||||
static void drawOptFlowMap(const CvMat* flow, CvMat* cflowmap, int step,
|
||||
double scale, CvScalar color)
|
||||
{
|
||||
int x, y;
|
||||
(void)scale;
|
||||
for( y = 0; y < cflowmap->rows; y += step)
|
||||
for( x = 0; x < cflowmap->cols; x += step)
|
||||
{
|
||||
CvPoint2D32f fxy = CV_MAT_ELEM(*flow, CvPoint2D32f, y, x);
|
||||
cvLine(cflowmap, cvPoint(x,y), cvPoint(cvRound(x+fxy.x), cvRound(y+fxy.y)),
|
||||
color, 1, 8, 0);
|
||||
cvCircle(cflowmap, cvPoint(x,y), 2, color, -1, 8, 0);
|
||||
}
|
||||
}
|
||||
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
CvCapture* capture = cvCreateCameraCapture(0);
|
||||
CvMat* prevgray = 0, *gray = 0, *flow = 0, *cflow = 0;
|
||||
(void)argc; (void)argv;
|
||||
|
||||
help();
|
||||
|
||||
if( !capture )
|
||||
return -1;
|
||||
|
||||
cvNamedWindow("flow", 1);
|
||||
|
||||
for(;;)
|
||||
{
|
||||
int firstFrame = gray == 0;
|
||||
IplImage* frame = cvQueryFrame(capture);
|
||||
if(!frame)
|
||||
break;
|
||||
if(!gray)
|
||||
{
|
||||
gray = cvCreateMat(frame->height, frame->width, CV_8UC1);
|
||||
prevgray = cvCreateMat(gray->rows, gray->cols, gray->type);
|
||||
flow = cvCreateMat(gray->rows, gray->cols, CV_32FC2);
|
||||
cflow = cvCreateMat(gray->rows, gray->cols, CV_8UC3);
|
||||
}
|
||||
cvCvtColor(frame, gray, CV_BGR2GRAY);
|
||||
|
||||
if( !firstFrame )
|
||||
{
|
||||
cvCalcOpticalFlowFarneback(prevgray, gray, flow, 0.5, 3, 15, 3, 5, 1.2, 0);
|
||||
cvCvtColor(prevgray, cflow, CV_GRAY2BGR);
|
||||
drawOptFlowMap(flow, cflow, 16, 1.5, CV_RGB(0, 255, 0));
|
||||
cvShowImage("flow", cflow);
|
||||
}
|
||||
if(cvWaitKey(30)>=0)
|
||||
break;
|
||||
{
|
||||
CvMat* temp;
|
||||
CV_SWAP(prevgray, gray, temp);
|
||||
}
|
||||
}
|
||||
cvReleaseCapture(&capture);
|
||||
return 0;
|
||||
}
|
||||
@@ -1,322 +0,0 @@
|
||||
/*
|
||||
* A Demo to OpenCV Implementation of SURF
|
||||
* Further Information Refer to "SURF: Speed-Up Robust Feature"
|
||||
* Author: Liu Liu
|
||||
* liuliu.1987+opencv@gmail.com
|
||||
*/
|
||||
#include "opencv2/objdetect/objdetect.hpp"
|
||||
#include "opencv2/features2d/features2d.hpp"
|
||||
#include "opencv2/calib3d/calib3d.hpp"
|
||||
#include "opencv2/nonfree/nonfree.hpp"
|
||||
#include "opencv2/imgproc/imgproc_c.h"
|
||||
#include "opencv2/highgui/highgui_c.h"
|
||||
#include "opencv2/legacy/legacy.hpp"
|
||||
#include "opencv2/legacy/compat.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <stdio.h>
|
||||
|
||||
using namespace std;
|
||||
static void help()
|
||||
{
|
||||
printf(
|
||||
"This program demonstrated the use of the SURF Detector and Descriptor using\n"
|
||||
"either FLANN (fast approx nearst neighbor classification) or brute force matching\n"
|
||||
"on planar objects.\n"
|
||||
"Usage:\n"
|
||||
"./find_obj <object_filename> <scene_filename>, default is box.png and box_in_scene.png\n\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// define whether to use approximate nearest-neighbor search
|
||||
#define USE_FLANN
|
||||
|
||||
#ifdef USE_FLANN
|
||||
static void
|
||||
flannFindPairs( const CvSeq*, const CvSeq* objectDescriptors,
|
||||
const CvSeq*, const CvSeq* imageDescriptors, vector<int>& ptpairs )
|
||||
{
|
||||
int length = (int)(objectDescriptors->elem_size/sizeof(float));
|
||||
|
||||
cv::Mat m_object(objectDescriptors->total, length, CV_32F);
|
||||
cv::Mat m_image(imageDescriptors->total, length, CV_32F);
|
||||
|
||||
|
||||
// copy descriptors
|
||||
CvSeqReader obj_reader;
|
||||
float* obj_ptr = m_object.ptr<float>(0);
|
||||
cvStartReadSeq( objectDescriptors, &obj_reader );
|
||||
for(int i = 0; i < objectDescriptors->total; i++ )
|
||||
{
|
||||
const float* descriptor = (const float*)obj_reader.ptr;
|
||||
CV_NEXT_SEQ_ELEM( obj_reader.seq->elem_size, obj_reader );
|
||||
memcpy(obj_ptr, descriptor, length*sizeof(float));
|
||||
obj_ptr += length;
|
||||
}
|
||||
CvSeqReader img_reader;
|
||||
float* img_ptr = m_image.ptr<float>(0);
|
||||
cvStartReadSeq( imageDescriptors, &img_reader );
|
||||
for(int i = 0; i < imageDescriptors->total; i++ )
|
||||
{
|
||||
const float* descriptor = (const float*)img_reader.ptr;
|
||||
CV_NEXT_SEQ_ELEM( img_reader.seq->elem_size, img_reader );
|
||||
memcpy(img_ptr, descriptor, length*sizeof(float));
|
||||
img_ptr += length;
|
||||
}
|
||||
|
||||
// find nearest neighbors using FLANN
|
||||
cv::Mat m_indices(objectDescriptors->total, 2, CV_32S);
|
||||
cv::Mat m_dists(objectDescriptors->total, 2, CV_32F);
|
||||
cv::flann::Index flann_index(m_image, cv::flann::KDTreeIndexParams(4)); // using 4 randomized kdtrees
|
||||
flann_index.knnSearch(m_object, m_indices, m_dists, 2, cv::flann::SearchParams(64) ); // maximum number of leafs checked
|
||||
|
||||
int* indices_ptr = m_indices.ptr<int>(0);
|
||||
float* dists_ptr = m_dists.ptr<float>(0);
|
||||
for (int i=0;i<m_indices.rows;++i) {
|
||||
if (dists_ptr[2*i]<0.6*dists_ptr[2*i+1]) {
|
||||
ptpairs.push_back(i);
|
||||
ptpairs.push_back(indices_ptr[2*i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
||||
static double
|
||||
compareSURFDescriptors( const float* d1, const float* d2, double best, int length )
|
||||
{
|
||||
double total_cost = 0;
|
||||
assert( length % 4 == 0 );
|
||||
for( int i = 0; i < length; i += 4 )
|
||||
{
|
||||
double t0 = d1[i ] - d2[i ];
|
||||
double t1 = d1[i+1] - d2[i+1];
|
||||
double t2 = d1[i+2] - d2[i+2];
|
||||
double t3 = d1[i+3] - d2[i+3];
|
||||
total_cost += t0*t0 + t1*t1 + t2*t2 + t3*t3;
|
||||
if( total_cost > best )
|
||||
break;
|
||||
}
|
||||
return total_cost;
|
||||
}
|
||||
|
||||
static int
|
||||
naiveNearestNeighbor( const float* vec, int laplacian,
|
||||
const CvSeq* model_keypoints,
|
||||
const CvSeq* model_descriptors )
|
||||
{
|
||||
int length = (int)(model_descriptors->elem_size/sizeof(float));
|
||||
int i, neighbor = -1;
|
||||
double d, dist1 = 1e6, dist2 = 1e6;
|
||||
CvSeqReader reader, kreader;
|
||||
cvStartReadSeq( model_keypoints, &kreader, 0 );
|
||||
cvStartReadSeq( model_descriptors, &reader, 0 );
|
||||
|
||||
for( i = 0; i < model_descriptors->total; i++ )
|
||||
{
|
||||
const CvSURFPoint* kp = (const CvSURFPoint*)kreader.ptr;
|
||||
const float* mvec = (const float*)reader.ptr;
|
||||
CV_NEXT_SEQ_ELEM( kreader.seq->elem_size, kreader );
|
||||
CV_NEXT_SEQ_ELEM( reader.seq->elem_size, reader );
|
||||
if( laplacian != kp->laplacian )
|
||||
continue;
|
||||
d = compareSURFDescriptors( vec, mvec, dist2, length );
|
||||
if( d < dist1 )
|
||||
{
|
||||
dist2 = dist1;
|
||||
dist1 = d;
|
||||
neighbor = i;
|
||||
}
|
||||
else if ( d < dist2 )
|
||||
dist2 = d;
|
||||
}
|
||||
if ( dist1 < 0.6*dist2 )
|
||||
return neighbor;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void
|
||||
findPairs( const CvSeq* objectKeypoints, const CvSeq* objectDescriptors,
|
||||
const CvSeq* imageKeypoints, const CvSeq* imageDescriptors, vector<int>& ptpairs )
|
||||
{
|
||||
int i;
|
||||
CvSeqReader reader, kreader;
|
||||
cvStartReadSeq( objectKeypoints, &kreader );
|
||||
cvStartReadSeq( objectDescriptors, &reader );
|
||||
ptpairs.clear();
|
||||
|
||||
for( i = 0; i < objectDescriptors->total; i++ )
|
||||
{
|
||||
const CvSURFPoint* kp = (const CvSURFPoint*)kreader.ptr;
|
||||
const float* descriptor = (const float*)reader.ptr;
|
||||
CV_NEXT_SEQ_ELEM( kreader.seq->elem_size, kreader );
|
||||
CV_NEXT_SEQ_ELEM( reader.seq->elem_size, reader );
|
||||
int nearest_neighbor = naiveNearestNeighbor( descriptor, kp->laplacian, imageKeypoints, imageDescriptors );
|
||||
if( nearest_neighbor >= 0 )
|
||||
{
|
||||
ptpairs.push_back(i);
|
||||
ptpairs.push_back(nearest_neighbor);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* a rough implementation for object location */
|
||||
static int
|
||||
locatePlanarObject( const CvSeq* objectKeypoints, const CvSeq* objectDescriptors,
|
||||
const CvSeq* imageKeypoints, const CvSeq* imageDescriptors,
|
||||
const CvPoint src_corners[4], CvPoint dst_corners[4] )
|
||||
{
|
||||
double h[9];
|
||||
CvMat _h = cvMat(3, 3, CV_64F, h);
|
||||
vector<int> ptpairs;
|
||||
vector<CvPoint2D32f> pt1, pt2;
|
||||
CvMat _pt1, _pt2;
|
||||
int i, n;
|
||||
|
||||
#ifdef USE_FLANN
|
||||
flannFindPairs( objectKeypoints, objectDescriptors, imageKeypoints, imageDescriptors, ptpairs );
|
||||
#else
|
||||
findPairs( objectKeypoints, objectDescriptors, imageKeypoints, imageDescriptors, ptpairs );
|
||||
#endif
|
||||
|
||||
n = (int)(ptpairs.size()/2);
|
||||
if( n < 4 )
|
||||
return 0;
|
||||
|
||||
pt1.resize(n);
|
||||
pt2.resize(n);
|
||||
for( i = 0; i < n; i++ )
|
||||
{
|
||||
pt1[i] = ((CvSURFPoint*)cvGetSeqElem(objectKeypoints,ptpairs[i*2]))->pt;
|
||||
pt2[i] = ((CvSURFPoint*)cvGetSeqElem(imageKeypoints,ptpairs[i*2+1]))->pt;
|
||||
}
|
||||
|
||||
_pt1 = cvMat(1, n, CV_32FC2, &pt1[0] );
|
||||
_pt2 = cvMat(1, n, CV_32FC2, &pt2[0] );
|
||||
if( !cvFindHomography( &_pt1, &_pt2, &_h, CV_RANSAC, 5 ))
|
||||
return 0;
|
||||
|
||||
for( i = 0; i < 4; i++ )
|
||||
{
|
||||
double x = src_corners[i].x, y = src_corners[i].y;
|
||||
double Z = 1./(h[6]*x + h[7]*y + h[8]);
|
||||
double X = (h[0]*x + h[1]*y + h[2])*Z;
|
||||
double Y = (h[3]*x + h[4]*y + h[5])*Z;
|
||||
dst_corners[i] = cvPoint(cvRound(X), cvRound(Y));
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
const char* object_filename = argc == 3 ? argv[1] : "box.png";
|
||||
const char* scene_filename = argc == 3 ? argv[2] : "box_in_scene.png";
|
||||
|
||||
cv::initModule_nonfree();
|
||||
help();
|
||||
|
||||
IplImage* object = cvLoadImage( object_filename, CV_LOAD_IMAGE_GRAYSCALE );
|
||||
IplImage* image = cvLoadImage( scene_filename, CV_LOAD_IMAGE_GRAYSCALE );
|
||||
if( !object || !image )
|
||||
{
|
||||
fprintf( stderr, "Can not load %s and/or %s\n",
|
||||
object_filename, scene_filename );
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
CvMemStorage* storage = cvCreateMemStorage(0);
|
||||
|
||||
cvNamedWindow("Object", 1);
|
||||
cvNamedWindow("Object Correspond", 1);
|
||||
|
||||
static cv::Scalar colors[] =
|
||||
{
|
||||
cv::Scalar(0,0,255),
|
||||
cv::Scalar(0,128,255),
|
||||
cv::Scalar(0,255,255),
|
||||
cv::Scalar(0,255,0),
|
||||
cv::Scalar(255,128,0),
|
||||
cv::Scalar(255,255,0),
|
||||
cv::Scalar(255,0,0),
|
||||
cv::Scalar(255,0,255),
|
||||
cv::Scalar(255,255,255)
|
||||
};
|
||||
|
||||
IplImage* object_color = cvCreateImage(cvGetSize(object), 8, 3);
|
||||
cvCvtColor( object, object_color, CV_GRAY2BGR );
|
||||
|
||||
CvSeq* objectKeypoints = 0, *objectDescriptors = 0;
|
||||
CvSeq* imageKeypoints = 0, *imageDescriptors = 0;
|
||||
int i;
|
||||
CvSURFParams params = cvSURFParams(500, 1);
|
||||
|
||||
double tt = (double)cvGetTickCount();
|
||||
cvExtractSURF( object, 0, &objectKeypoints, &objectDescriptors, storage, params );
|
||||
printf("Object Descriptors: %d\n", objectDescriptors->total);
|
||||
|
||||
cvExtractSURF( image, 0, &imageKeypoints, &imageDescriptors, storage, params );
|
||||
printf("Image Descriptors: %d\n", imageDescriptors->total);
|
||||
tt = (double)cvGetTickCount() - tt;
|
||||
|
||||
printf( "Extraction time = %gms\n", tt/(cvGetTickFrequency()*1000.));
|
||||
|
||||
CvPoint src_corners[4] = {CvPoint(0,0), CvPoint(object->width,0), CvPoint(object->width, object->height), CvPoint(0, object->height)};
|
||||
CvPoint dst_corners[4];
|
||||
IplImage* correspond = cvCreateImage( cvSize(image->width, object->height+image->height), 8, 1 );
|
||||
cvSetImageROI( correspond, cvRect( 0, 0, object->width, object->height ) );
|
||||
cvCopy( object, correspond );
|
||||
cvSetImageROI( correspond, cvRect( 0, object->height, correspond->width, correspond->height ) );
|
||||
cvCopy( image, correspond );
|
||||
cvResetImageROI( correspond );
|
||||
|
||||
#ifdef USE_FLANN
|
||||
printf("Using approximate nearest neighbor search\n");
|
||||
#endif
|
||||
|
||||
if( locatePlanarObject( objectKeypoints, objectDescriptors, imageKeypoints,
|
||||
imageDescriptors, src_corners, dst_corners ))
|
||||
{
|
||||
for( i = 0; i < 4; i++ )
|
||||
{
|
||||
CvPoint r1 = dst_corners[i%4];
|
||||
CvPoint r2 = dst_corners[(i+1)%4];
|
||||
cvLine( correspond, cvPoint(r1.x, r1.y+object->height ),
|
||||
cvPoint(r2.x, r2.y+object->height ), colors[8] );
|
||||
}
|
||||
}
|
||||
vector<int> ptpairs;
|
||||
#ifdef USE_FLANN
|
||||
flannFindPairs( objectKeypoints, objectDescriptors, imageKeypoints, imageDescriptors, ptpairs );
|
||||
#else
|
||||
findPairs( objectKeypoints, objectDescriptors, imageKeypoints, imageDescriptors, ptpairs );
|
||||
#endif
|
||||
for( i = 0; i < (int)ptpairs.size(); i += 2 )
|
||||
{
|
||||
CvSURFPoint* r1 = (CvSURFPoint*)cvGetSeqElem( objectKeypoints, ptpairs[i] );
|
||||
CvSURFPoint* r2 = (CvSURFPoint*)cvGetSeqElem( imageKeypoints, ptpairs[i+1] );
|
||||
cvLine( correspond, cvPointFrom32f(r1->pt),
|
||||
cvPoint(cvRound(r2->pt.x), cvRound(r2->pt.y+object->height)), colors[8] );
|
||||
}
|
||||
|
||||
cvShowImage( "Object Correspond", correspond );
|
||||
for( i = 0; i < objectKeypoints->total; i++ )
|
||||
{
|
||||
CvSURFPoint* r = (CvSURFPoint*)cvGetSeqElem( objectKeypoints, i );
|
||||
CvPoint center;
|
||||
int radius;
|
||||
center.x = cvRound(r->pt.x);
|
||||
center.y = cvRound(r->pt.y);
|
||||
radius = cvRound(r->size*1.2/9.*2);
|
||||
cvCircle( object_color, center, radius, colors[0], 1, 8, 0 );
|
||||
}
|
||||
cvShowImage( "Object", object_color );
|
||||
|
||||
cvWaitKey(0);
|
||||
|
||||
cvDestroyWindow("Object");
|
||||
cvDestroyWindow("Object Correspond");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,166 +0,0 @@
|
||||
#include "opencv2/highgui/highgui.hpp"
|
||||
#include "opencv2/core/core.hpp"
|
||||
#include "opencv2/imgproc/imgproc.hpp"
|
||||
#include "opencv2/features2d/features2d.hpp"
|
||||
#include "opencv2/nonfree/nonfree.hpp"
|
||||
#include "opencv2/legacy/legacy.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
|
||||
static void help()
|
||||
{
|
||||
cout << "This program shows the use of the Calonder point descriptor classifier"
|
||||
"SURF is used to detect interest points, Calonder is used to describe/match these points\n"
|
||||
"Format:" << endl <<
|
||||
" classifier_file(to write) test_image file_with_train_images_filenames(txt)" <<
|
||||
" or" << endl <<
|
||||
" classifier_file(to read) test_image" << "\n" << endl <<
|
||||
"Using OpenCV version " << CV_VERSION << "\n" << endl;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Generates random perspective transform of image
|
||||
*/
|
||||
static void warpPerspectiveRand( const Mat& src, Mat& dst, Mat& H, RNG& rng )
|
||||
{
|
||||
H.create(3, 3, CV_32FC1);
|
||||
H.at<float>(0,0) = rng.uniform( 0.8f, 1.2f);
|
||||
H.at<float>(0,1) = rng.uniform(-0.1f, 0.1f);
|
||||
H.at<float>(0,2) = rng.uniform(-0.1f, 0.1f)*src.cols;
|
||||
H.at<float>(1,0) = rng.uniform(-0.1f, 0.1f);
|
||||
H.at<float>(1,1) = rng.uniform( 0.8f, 1.2f);
|
||||
H.at<float>(1,2) = rng.uniform(-0.1f, 0.1f)*src.rows;
|
||||
H.at<float>(2,0) = rng.uniform( -1e-4f, 1e-4f);
|
||||
H.at<float>(2,1) = rng.uniform( -1e-4f, 1e-4f);
|
||||
H.at<float>(2,2) = rng.uniform( 0.8f, 1.2f);
|
||||
|
||||
warpPerspective( src, dst, H, src.size() );
|
||||
}
|
||||
|
||||
/*
|
||||
* Trains Calonder classifier and writes trained classifier in file:
|
||||
* imgFilename - name of .txt file which contains list of full filenames of train images,
|
||||
* classifierFilename - name of binary file in which classifier will be written.
|
||||
*
|
||||
* To train Calonder classifier RTreeClassifier class need to be used.
|
||||
*/
|
||||
static void trainCalonderClassifier( const string& classifierFilename, const string& imgFilename )
|
||||
{
|
||||
// Reads train images
|
||||
ifstream is( imgFilename.c_str(), ifstream::in );
|
||||
vector<Mat> trainImgs;
|
||||
while( !is.eof() )
|
||||
{
|
||||
string str;
|
||||
getline( is, str );
|
||||
if (str.empty()) break;
|
||||
Mat img = imread( str, IMREAD_GRAYSCALE );
|
||||
if( !img.empty() )
|
||||
trainImgs.push_back( img );
|
||||
}
|
||||
if( trainImgs.empty() )
|
||||
{
|
||||
cout << "All train images can not be read." << endl;
|
||||
exit(-1);
|
||||
}
|
||||
cout << trainImgs.size() << " train images were read." << endl;
|
||||
|
||||
// Extracts keypoints from train images
|
||||
SurfFeatureDetector detector;
|
||||
vector<BaseKeypoint> trainPoints;
|
||||
vector<IplImage> iplTrainImgs(trainImgs.size());
|
||||
for( size_t imgIdx = 0; imgIdx < trainImgs.size(); imgIdx++ )
|
||||
{
|
||||
iplTrainImgs[imgIdx] = trainImgs[imgIdx];
|
||||
vector<KeyPoint> kps; detector.detect( trainImgs[imgIdx], kps );
|
||||
|
||||
for( size_t pointIdx = 0; pointIdx < kps.size(); pointIdx++ )
|
||||
{
|
||||
Point2f p = kps[pointIdx].pt;
|
||||
trainPoints.push_back( BaseKeypoint(cvRound(p.x), cvRound(p.y), &iplTrainImgs[imgIdx]) );
|
||||
}
|
||||
}
|
||||
|
||||
// Trains Calonder classifier on extracted points
|
||||
RTreeClassifier classifier;
|
||||
classifier.train( trainPoints, theRNG(), 48, 9, 100 );
|
||||
// Writes classifier
|
||||
classifier.write( classifierFilename.c_str() );
|
||||
}
|
||||
|
||||
/*
|
||||
* Test Calonder classifier to match keypoints on given image:
|
||||
* classifierFilename - name of file from which classifier will be read,
|
||||
* imgFilename - test image filename.
|
||||
*
|
||||
* To calculate keypoint descriptors you may use RTreeClassifier class (as to train),
|
||||
* but it is convenient to use CalonderDescriptorExtractor class which is wrapper of
|
||||
* RTreeClassifier.
|
||||
*/
|
||||
static void testCalonderClassifier( const string& classifierFilename, const string& imgFilename )
|
||||
{
|
||||
Mat img1 = imread( imgFilename, IMREAD_GRAYSCALE ), img2, H12;
|
||||
if( img1.empty() )
|
||||
{
|
||||
cout << "Test image can not be read." << endl;
|
||||
exit(-1);
|
||||
}
|
||||
warpPerspectiveRand( img1, img2, H12, theRNG() );
|
||||
|
||||
// Exstract keypoints from test images
|
||||
SurfFeatureDetector detector;
|
||||
vector<KeyPoint> keypoints1; detector.detect( img1, keypoints1 );
|
||||
vector<KeyPoint> keypoints2; detector.detect( img2, keypoints2 );
|
||||
|
||||
// Compute descriptors
|
||||
CalonderDescriptorExtractor<float> de( classifierFilename );
|
||||
Mat descriptors1; de.compute( img1, keypoints1, descriptors1 );
|
||||
Mat descriptors2; de.compute( img2, keypoints2, descriptors2 );
|
||||
|
||||
// Match descriptors
|
||||
BFMatcher matcher(de.defaultNorm());
|
||||
vector<DMatch> matches;
|
||||
matcher.match( descriptors1, descriptors2, matches );
|
||||
|
||||
// Prepare inlier mask
|
||||
vector<char> matchesMask( matches.size(), 0 );
|
||||
vector<Point2f> points1; KeyPoint::convert( keypoints1, points1 );
|
||||
vector<Point2f> points2; KeyPoint::convert( keypoints2, points2 );
|
||||
Mat points1t; perspectiveTransform(Mat(points1), points1t, H12);
|
||||
for( size_t mi = 0; mi < matches.size(); mi++ )
|
||||
{
|
||||
if( norm(points2[matches[mi].trainIdx] - points1t.at<Point2f>((int)mi,0)) < 4 ) // inlier
|
||||
matchesMask[mi] = 1;
|
||||
}
|
||||
|
||||
// Draw
|
||||
Mat drawImg;
|
||||
drawMatches( img1, keypoints1, img2, keypoints2, matches, drawImg, CV_RGB(0, 255, 0), CV_RGB(0, 0, 255), matchesMask );
|
||||
string winName = "Matches";
|
||||
namedWindow( winName, WINDOW_AUTOSIZE );
|
||||
imshow( winName, drawImg );
|
||||
waitKey();
|
||||
}
|
||||
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
if( argc != 4 && argc != 3 )
|
||||
{
|
||||
help();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if( argc == 4 )
|
||||
trainCalonderClassifier( argv[1], argv[3] );
|
||||
|
||||
testCalonderClassifier( argv[1], argv[2] );
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,157 +0,0 @@
|
||||
#include "opencv2/core/utility.hpp"
|
||||
#include "opencv2/highgui.hpp"
|
||||
#include "opencv2/imgproc.hpp"
|
||||
#include "opencv2/features2d.hpp"
|
||||
#include "opencv2/objdetect.hpp"
|
||||
#include "opencv2/legacy.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <stdio.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
|
||||
static void help()
|
||||
{
|
||||
printf( "This program shows the use of the \"fern\" plannar PlanarObjectDetector point\n"
|
||||
"descriptor classifier\n"
|
||||
"Usage:\n"
|
||||
"./find_obj_ferns <object_filename> <scene_filename>, default: box.png and box_in_scene.png\n\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
int i;
|
||||
|
||||
const char* object_filename = argc > 1 ? argv[1] : "box.png";
|
||||
const char* scene_filename = argc > 2 ? argv[2] : "box_in_scene.png";
|
||||
|
||||
help();
|
||||
|
||||
Mat object = imread( object_filename, IMREAD_GRAYSCALE );
|
||||
Mat scene = imread( scene_filename, IMREAD_GRAYSCALE );
|
||||
|
||||
if( !object.data || !scene.data )
|
||||
{
|
||||
fprintf( stderr, "Can not load %s and/or %s\n",
|
||||
object_filename, scene_filename );
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
double imgscale = 1;
|
||||
Mat image;
|
||||
|
||||
resize(scene, image, Size(), 1./imgscale, 1./imgscale, INTER_CUBIC);
|
||||
|
||||
namedWindow("Object", 1);
|
||||
namedWindow("Image", 1);
|
||||
namedWindow("Object Correspondence", 1);
|
||||
|
||||
Size patchSize(32, 32);
|
||||
LDetector ldetector(7, 20, 2, 2000, patchSize.width, 2);
|
||||
ldetector.setVerbose(true);
|
||||
PlanarObjectDetector detector;
|
||||
|
||||
vector<Mat> objpyr, imgpyr;
|
||||
int blurKSize = 3;
|
||||
double sigma = 0;
|
||||
GaussianBlur(object, object, Size(blurKSize, blurKSize), sigma, sigma);
|
||||
GaussianBlur(image, image, Size(blurKSize, blurKSize), sigma, sigma);
|
||||
buildPyramid(object, objpyr, ldetector.nOctaves-1);
|
||||
buildPyramid(image, imgpyr, ldetector.nOctaves-1);
|
||||
|
||||
vector<KeyPoint> objKeypoints, imgKeypoints;
|
||||
PatchGenerator gen(0,256,5,true,0.8,1.2,-CV_PI/2,CV_PI/2,-CV_PI/2,CV_PI/2);
|
||||
|
||||
string model_filename = format("%s_model.xml.gz", object_filename);
|
||||
printf("Trying to load %s ...\n", model_filename.c_str());
|
||||
FileStorage fs(model_filename, FileStorage::READ);
|
||||
if( fs.isOpened() )
|
||||
{
|
||||
detector.read(fs.getFirstTopLevelNode());
|
||||
printf("Successfully loaded %s.\n", model_filename.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("The file not found and can not be read. Let's train the model.\n");
|
||||
printf("Step 1. Finding the robust keypoints ...\n");
|
||||
ldetector.setVerbose(true);
|
||||
ldetector.getMostStable2D(object, objKeypoints, 100, gen);
|
||||
printf("Done.\nStep 2. Training ferns-based planar object detector ...\n");
|
||||
detector.setVerbose(true);
|
||||
|
||||
detector.train(objpyr, objKeypoints, patchSize.width, 100, 11, 10000, ldetector, gen);
|
||||
printf("Done.\nStep 3. Saving the model to %s ...\n", model_filename.c_str());
|
||||
if( fs.open(model_filename, FileStorage::WRITE) )
|
||||
detector.write(fs, "ferns_model");
|
||||
}
|
||||
printf("Now find the keypoints in the image, try recognize them and compute the homography matrix\n");
|
||||
fs.release();
|
||||
|
||||
vector<Point2f> dst_corners;
|
||||
Mat correspond( object.rows + image.rows, std::max(object.cols, image.cols), CV_8UC3);
|
||||
correspond = Scalar(0.);
|
||||
Mat part(correspond, Rect(0, 0, object.cols, object.rows));
|
||||
cvtColor(object, part, CV_GRAY2BGR);
|
||||
part = Mat(correspond, Rect(0, object.rows, image.cols, image.rows));
|
||||
cvtColor(image, part, CV_GRAY2BGR);
|
||||
|
||||
vector<int> pairs;
|
||||
Mat H;
|
||||
|
||||
double t = (double)getTickCount();
|
||||
objKeypoints = detector.getModelPoints();
|
||||
ldetector(imgpyr, imgKeypoints, 300);
|
||||
|
||||
std::cout << "Object keypoints: " << objKeypoints.size() << "\n";
|
||||
std::cout << "Image keypoints: " << imgKeypoints.size() << "\n";
|
||||
bool found = detector(imgpyr, imgKeypoints, H, dst_corners, &pairs);
|
||||
t = (double)getTickCount() - t;
|
||||
printf("%gms\n", t*1000/getTickFrequency());
|
||||
|
||||
if( found )
|
||||
{
|
||||
for( i = 0; i < 4; i++ )
|
||||
{
|
||||
Point r1 = dst_corners[i%4];
|
||||
Point r2 = dst_corners[(i+1)%4];
|
||||
line( correspond, Point(r1.x, r1.y+object.rows),
|
||||
Point(r2.x, r2.y+object.rows), Scalar(0,0,255) );
|
||||
}
|
||||
}
|
||||
|
||||
for( i = 0; i < (int)pairs.size(); i += 2 )
|
||||
{
|
||||
line( correspond, objKeypoints[pairs[i]].pt,
|
||||
imgKeypoints[pairs[i+1]].pt + Point2f(0,(float)object.rows),
|
||||
Scalar(0,255,0) );
|
||||
}
|
||||
|
||||
imshow( "Object Correspondence", correspond );
|
||||
Mat objectColor;
|
||||
cvtColor(object, objectColor, CV_GRAY2BGR);
|
||||
for( i = 0; i < (int)objKeypoints.size(); i++ )
|
||||
{
|
||||
circle( objectColor, objKeypoints[i].pt, 2, Scalar(0,0,255), -1 );
|
||||
circle( objectColor, objKeypoints[i].pt, (1 << objKeypoints[i].octave)*15, Scalar(0,255,0), 1 );
|
||||
}
|
||||
Mat imageColor;
|
||||
cvtColor(image, imageColor, CV_GRAY2BGR);
|
||||
for( i = 0; i < (int)imgKeypoints.size(); i++ )
|
||||
{
|
||||
circle( imageColor, imgKeypoints[i].pt, 2, Scalar(0,0,255), -1 );
|
||||
circle( imageColor, imgKeypoints[i].pt, (1 << imgKeypoints[i].octave)*15, Scalar(0,255,0), 1 );
|
||||
}
|
||||
|
||||
imwrite("correspond.png", correspond );
|
||||
imshow( "Object", objectColor );
|
||||
imshow( "Image", imageColor );
|
||||
|
||||
waitKey(0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Before Width: | Height: | Size: 80 KiB |
@@ -1,88 +0,0 @@
|
||||
#include "opencv2/objdetect/objdetect_c.h"
|
||||
#include "opencv2/highgui/highgui_c.h"
|
||||
#include "opencv2/core/utility.hpp"
|
||||
#include <stdio.h>
|
||||
|
||||
using namespace cv;
|
||||
|
||||
static void help()
|
||||
{
|
||||
printf( "This program demonstrated the use of the latentSVM detector.\n"
|
||||
"It reads in a trained object model and then uses that to detect the object in an image\n"
|
||||
"Call:\n"
|
||||
"./latentsvmdetect [<image_filename> <model_filename> [<threads_number>]]\n"
|
||||
" The defaults for image_filename and model_filename are cat.jpg and cat.xml respectively\n"
|
||||
" Press any key to quit.\n");
|
||||
}
|
||||
|
||||
const char* model_filename = "cat.xml";
|
||||
const char* image_filename = "cat.jpg";
|
||||
int tbbNumThreads = -1;
|
||||
|
||||
static void detect_and_draw_objects( IplImage* image, CvLatentSvmDetector* detector, int numThreads = -1)
|
||||
{
|
||||
CvMemStorage* storage = cvCreateMemStorage(0);
|
||||
CvSeq* detections = 0;
|
||||
int i = 0;
|
||||
int64 start = 0, finish = 0;
|
||||
|
||||
setNumThreads(numThreads);
|
||||
numThreads = getNumThreads();
|
||||
printf("Number of threads %i\n", numThreads);
|
||||
|
||||
start = cvGetTickCount();
|
||||
detections = cvLatentSvmDetectObjects(image, detector, storage, 0.5f, numThreads);
|
||||
finish = cvGetTickCount();
|
||||
printf("detection time = %.3f\n", (float)(finish - start) / (float)(cvGetTickFrequency() * 1000000.0));
|
||||
setNumThreads(-1);
|
||||
|
||||
for( i = 0; i < detections->total; i++ )
|
||||
{
|
||||
CvObjectDetection detection = *(CvObjectDetection*)cvGetSeqElem( detections, i );
|
||||
float score = detection.score;
|
||||
CvRect bounding_box = detection.rect;
|
||||
cvRectangle( image, cvPoint(bounding_box.x, bounding_box.y),
|
||||
cvPoint(bounding_box.x + bounding_box.width,
|
||||
bounding_box.y + bounding_box.height),
|
||||
CV_RGB(cvRound(255.0f*score),0,0), 3 );
|
||||
}
|
||||
cvReleaseMemStorage( &storage );
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
help();
|
||||
if (argc > 2)
|
||||
{
|
||||
image_filename = argv[1];
|
||||
model_filename = argv[2];
|
||||
if (argc > 3)
|
||||
{
|
||||
tbbNumThreads = atoi(argv[3]);
|
||||
}
|
||||
}
|
||||
IplImage* image = cvLoadImage(image_filename);
|
||||
if (!image)
|
||||
{
|
||||
printf( "Unable to load the image\n"
|
||||
"Pass it as the first parameter: latentsvmdetect <path to cat.jpg> <path to cat.xml>\n" );
|
||||
return -1;
|
||||
}
|
||||
CvLatentSvmDetector* detector = cvLoadLatentSvmDetector(model_filename);
|
||||
if (!detector)
|
||||
{
|
||||
printf( "Unable to load the model\n"
|
||||
"Pass it as the second parameter: latentsvmdetect <path to cat.jpg> <path to cat.xml>\n" );
|
||||
cvReleaseImage( &image );
|
||||
return -1;
|
||||
}
|
||||
detect_and_draw_objects( image, detector, tbbNumThreads );
|
||||
cvNamedWindow( "test", 0 );
|
||||
cvShowImage( "test", image );
|
||||
cvWaitKey(0);
|
||||
cvReleaseLatentSvmDetector( &detector );
|
||||
cvReleaseImage( &image );
|
||||
cvDestroyAllWindows();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Before Width: | Height: | Size: 90 KiB |
@@ -1,130 +0,0 @@
|
||||
#include "opencv2/highgui/highgui_c.h"
|
||||
#include "opencv2/imgproc/imgproc_c.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
IplImage* src = 0;
|
||||
IplImage* dst = 0;
|
||||
|
||||
IplConvKernel* element = 0;
|
||||
int element_shape = CV_SHAPE_RECT;
|
||||
|
||||
//the address of variable which receives trackbar position update
|
||||
int max_iters = 10;
|
||||
int open_close_pos = 0;
|
||||
int erode_dilate_pos = 0;
|
||||
|
||||
// callback function for open/close trackbar
|
||||
static void OpenClose(int pos)
|
||||
{
|
||||
int n = open_close_pos - max_iters;
|
||||
int an = n > 0 ? n : -n;
|
||||
(void)pos;
|
||||
|
||||
element = cvCreateStructuringElementEx( an*2+1, an*2+1, an, an, element_shape, 0 );
|
||||
if( n < 0 )
|
||||
{
|
||||
cvErode(src,dst,element,1);
|
||||
cvDilate(dst,dst,element,1);
|
||||
}
|
||||
else
|
||||
{
|
||||
cvDilate(src,dst,element,1);
|
||||
cvErode(dst,dst,element,1);
|
||||
}
|
||||
cvReleaseStructuringElement(&element);
|
||||
cvShowImage("Open/Close",dst);
|
||||
}
|
||||
|
||||
// callback function for erode/dilate trackbar
|
||||
static void ErodeDilate(int pos)
|
||||
{
|
||||
int n = erode_dilate_pos - max_iters;
|
||||
int an = n > 0 ? n : -n;
|
||||
(void)pos;
|
||||
|
||||
element = cvCreateStructuringElementEx( an*2+1, an*2+1, an, an, element_shape, 0 );
|
||||
if( n < 0 )
|
||||
{
|
||||
cvErode(src,dst,element,1);
|
||||
}
|
||||
else
|
||||
{
|
||||
cvDilate(src,dst,element,1);
|
||||
}
|
||||
cvReleaseStructuringElement(&element);
|
||||
cvShowImage("Erode/Dilate",dst);
|
||||
}
|
||||
|
||||
static void help(void)
|
||||
{
|
||||
printf( "This program demonstrated the use of the morphology operator, especially open, close, erode, dilate operations\n"
|
||||
"Morphology operators are built on max (close) and min (open) operators as measured by pixels covered by small structuring elements.\n"
|
||||
"These operators are very efficient.\n"
|
||||
"This program also allows you to play with elliptical, rectangluar and cross structure elements\n"
|
||||
"Usage: \n"
|
||||
"./morphologyc [image_name -- Default baboon.jpg]\n"
|
||||
"\nHot keys: \n"
|
||||
"\tESC - quit the program\n"
|
||||
"\tr - use rectangle structuring element\n"
|
||||
"\te - use elliptic structuring element\n"
|
||||
"\tc - use cross-shaped structuring element\n"
|
||||
"\tSPACE - loop through all the options\n" );
|
||||
}
|
||||
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
char* filename = 0;
|
||||
|
||||
help();
|
||||
|
||||
filename = argc == 2 ? argv[1] : (char*)"baboon.jpg";
|
||||
if( (src = cvLoadImage(filename,1)) == 0 )
|
||||
{
|
||||
printf("Cannot load file image %s\n", filename);
|
||||
help();
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
dst = cvCloneImage(src);
|
||||
|
||||
//create windows for output images
|
||||
cvNamedWindow("Open/Close",1);
|
||||
cvNamedWindow("Erode/Dilate",1);
|
||||
|
||||
open_close_pos = erode_dilate_pos = max_iters;
|
||||
cvCreateTrackbar("iterations", "Open/Close",&open_close_pos,max_iters*2+1,OpenClose);
|
||||
cvCreateTrackbar("iterations", "Erode/Dilate",&erode_dilate_pos,max_iters*2+1,ErodeDilate);
|
||||
|
||||
for(;;)
|
||||
{
|
||||
int c;
|
||||
|
||||
OpenClose(open_close_pos);
|
||||
ErodeDilate(erode_dilate_pos);
|
||||
c = cvWaitKey(0);
|
||||
|
||||
if( (char)c == 27 )
|
||||
break;
|
||||
if( (char)c == 'e' )
|
||||
element_shape = CV_SHAPE_ELLIPSE;
|
||||
else if( (char)c == 'r' )
|
||||
element_shape = CV_SHAPE_RECT;
|
||||
else if( (char)c == 'c' )
|
||||
element_shape = CV_SHAPE_CROSS;
|
||||
else if( (char)c == ' ' )
|
||||
element_shape = (element_shape + 1) % 3;
|
||||
}
|
||||
|
||||
//release images
|
||||
cvReleaseImage(&src);
|
||||
cvReleaseImage(&dst);
|
||||
|
||||
//destroy windows
|
||||
cvDestroyWindow("Open/Close");
|
||||
cvDestroyWindow("Erode/Dilate");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,87 +0,0 @@
|
||||
/* This sample code was originally provided by Liu Liu
|
||||
* Copyright (C) 2009, Liu Liu All rights reserved.
|
||||
*/
|
||||
|
||||
#include <opencv2/core/utility.hpp>
|
||||
#include "opencv2/highgui.hpp"
|
||||
#include "opencv2/features2d.hpp"
|
||||
#include "opencv2/imgproc.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <stdio.h>
|
||||
|
||||
using namespace cv;
|
||||
using namespace std;
|
||||
|
||||
static void help()
|
||||
{
|
||||
cout << "\nThis program demonstrates the Maximal Extremal Region interest point detector.\n"
|
||||
"It finds the most stable (in size) dark and white regions as a threshold is increased.\n"
|
||||
"\nCall:\n"
|
||||
"./mser_sample <path_and_image_filename, Default is 'puzzle.png'>\n\n";
|
||||
}
|
||||
|
||||
static const Vec3b bcolors[] =
|
||||
{
|
||||
Vec3b(0,0,255),
|
||||
Vec3b(0,128,255),
|
||||
Vec3b(0,255,255),
|
||||
Vec3b(0,255,0),
|
||||
Vec3b(255,128,0),
|
||||
Vec3b(255,255,0),
|
||||
Vec3b(255,0,0),
|
||||
Vec3b(255,0,255),
|
||||
Vec3b(255,255,255)
|
||||
};
|
||||
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
string path;
|
||||
Mat img0, img, yuv, gray, ellipses;
|
||||
help();
|
||||
|
||||
img0 = imread( argc != 2 ? "puzzle.png" : argv[1], 1 );
|
||||
if( img0.empty() )
|
||||
{
|
||||
if( argc != 2 )
|
||||
cout << "\nUsage: mser_sample <path_to_image>\n";
|
||||
else
|
||||
cout << "Unable to load image " << argv[1] << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
cvtColor(img0, yuv, COLOR_BGR2YCrCb);
|
||||
cvtColor(img0, gray, COLOR_BGR2GRAY);
|
||||
cvtColor(gray, img, COLOR_GRAY2BGR);
|
||||
img.copyTo(ellipses);
|
||||
|
||||
vector<vector<Point> > contours;
|
||||
double t = (double)getTickCount();
|
||||
MSER()(yuv, contours);
|
||||
t = (double)getTickCount() - t;
|
||||
printf( "MSER extracted %d contours in %g ms.\n", (int)contours.size(),
|
||||
t*1000./getTickFrequency() );
|
||||
|
||||
// draw mser's with different colors
|
||||
for( int i = (int)contours.size()-1; i >= 0; i-- )
|
||||
{
|
||||
const vector<Point>& r = contours[i];
|
||||
for ( int j = 0; j < (int)r.size(); j++ )
|
||||
{
|
||||
Point pt = r[j];
|
||||
img.at<Vec3b>(pt) = bcolors[i%9];
|
||||
}
|
||||
|
||||
// find ellipse (it seems cvfitellipse2 have error or sth?)
|
||||
RotatedRect box = fitEllipse( r );
|
||||
|
||||
box.angle=(float)CV_PI/2-box.angle;
|
||||
ellipse( ellipses, box, Scalar(196,255,255), 2 );
|
||||
}
|
||||
|
||||
imshow( "original", img0 );
|
||||
imshow( "response", img );
|
||||
imshow( "ellipses", ellipses );
|
||||
|
||||
waitKey(0);
|
||||
}
|
||||
@@ -1,119 +0,0 @@
|
||||
/*
|
||||
* one_way_sample.cpp
|
||||
* outlet_detection
|
||||
*
|
||||
* Created by Victor Eruhimov on 8/5/09.
|
||||
* Copyright 2009 Argus Corp. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "opencv2/imgproc/imgproc.hpp"
|
||||
#include "opencv2/features2d/features2d.hpp"
|
||||
#include "opencv2/highgui/highgui.hpp"
|
||||
#include "opencv2/imgproc/imgproc_c.h"
|
||||
#include "opencv2/nonfree/nonfree.hpp"
|
||||
#include "opencv2/legacy/legacy.hpp"
|
||||
#include "opencv2/legacy/compat.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <stdio.h>
|
||||
|
||||
static void help()
|
||||
{
|
||||
printf("\nThis program demonstrates the one way interest point descriptor found in features2d.hpp\n"
|
||||
"Correspondences are drawn\n");
|
||||
printf("Format: \n./one_way_sample <path_to_samples> <image1> <image2>\n");
|
||||
printf("For example: ./one_way_sample . ../c/scene_l.bmp ../c/scene_r.bmp\n");
|
||||
}
|
||||
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
|
||||
Mat DrawCorrespondences(const Mat& img1, const vector<KeyPoint>& features1, const Mat& img2,
|
||||
const vector<KeyPoint>& features2, const vector<int>& desc_idx);
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
const char images_list[] = "one_way_train_images.txt";
|
||||
const CvSize patch_size = cvSize(24, 24);
|
||||
const int pose_count = 50;
|
||||
|
||||
if (argc != 4)
|
||||
{
|
||||
help();
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string path_name = argv[1];
|
||||
std::string img1_name = path_name + "/" + std::string(argv[2]);
|
||||
std::string img2_name = path_name + "/" + std::string(argv[3]);
|
||||
|
||||
printf("Reading the images...\n");
|
||||
Mat img1 = imread(img1_name, IMREAD_GRAYSCALE);
|
||||
Mat img2 = imread(img2_name, IMREAD_GRAYSCALE);
|
||||
|
||||
// extract keypoints from the first image
|
||||
SURF surf_extractor(5.0e3);
|
||||
vector<KeyPoint> keypoints1;
|
||||
|
||||
// printf("Extracting keypoints\n");
|
||||
surf_extractor(img1, Mat(), keypoints1);
|
||||
|
||||
printf("Extracted %d keypoints...\n", (int)keypoints1.size());
|
||||
|
||||
printf("Training one way descriptors... \n");
|
||||
// create descriptors
|
||||
OneWayDescriptorBase descriptors(patch_size, pose_count, OneWayDescriptorBase::GetPCAFilename(), path_name,
|
||||
images_list);
|
||||
IplImage img1_c = img1;
|
||||
IplImage img2_c = img2;
|
||||
descriptors.CreateDescriptorsFromImage(&img1_c, keypoints1);
|
||||
printf("done\n");
|
||||
|
||||
// extract keypoints from the second image
|
||||
vector<KeyPoint> keypoints2;
|
||||
surf_extractor(img2, Mat(), keypoints2);
|
||||
printf("Extracted %d keypoints from the second image...\n", (int)keypoints2.size());
|
||||
|
||||
printf("Finding nearest neighbors...");
|
||||
// find NN for each of keypoints2 in keypoints1
|
||||
vector<int> desc_idx;
|
||||
desc_idx.resize(keypoints2.size());
|
||||
for (size_t i = 0; i < keypoints2.size(); i++)
|
||||
{
|
||||
int pose_idx = 0;
|
||||
float distance = 0;
|
||||
descriptors.FindDescriptor(&img2_c, keypoints2[i].pt, desc_idx[i], pose_idx, distance);
|
||||
}
|
||||
printf("done\n");
|
||||
|
||||
Mat img_corr = DrawCorrespondences(img1, keypoints1, img2, keypoints2, desc_idx);
|
||||
|
||||
imshow("correspondences", img_corr);
|
||||
waitKey(0);
|
||||
}
|
||||
|
||||
Mat DrawCorrespondences(const Mat& img1, const vector<KeyPoint>& features1, const Mat& img2,
|
||||
const vector<KeyPoint>& features2, const vector<int>& desc_idx)
|
||||
{
|
||||
Mat part, img_corr(Size(img1.cols + img2.cols, MAX(img1.rows, img2.rows)), CV_8UC3);
|
||||
img_corr = Scalar::all(0);
|
||||
part = img_corr(Rect(0, 0, img1.cols, img1.rows));
|
||||
cvtColor(img1, part, COLOR_GRAY2RGB);
|
||||
part = img_corr(Rect(img1.cols, 0, img2.cols, img2.rows));
|
||||
cvtColor(img1, part, COLOR_GRAY2RGB);
|
||||
|
||||
for (size_t i = 0; i < features1.size(); i++)
|
||||
{
|
||||
circle(img_corr, features1[i].pt, 3, CV_RGB(255, 0, 0));
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < features2.size(); i++)
|
||||
{
|
||||
Point pt((int)features2[i].pt.x + img1.cols, (int)features2[i].pt.y);
|
||||
circle(img_corr, pt, 3, Scalar(0, 0, 255));
|
||||
line(img_corr, features1[desc_idx[i]].pt, pt, Scalar(0, 255, 0));
|
||||
}
|
||||
|
||||
return img_corr;
|
||||
}
|
||||
|
Before Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 29 KiB |
@@ -1,2 +0,0 @@
|
||||
one_way_train_0000.jpg
|
||||
one_way_train_0001.jpg
|
||||
@@ -1,98 +0,0 @@
|
||||
#include "opencv2/imgproc/imgproc_c.h"
|
||||
#include "opencv2/highgui/highgui_c.h"
|
||||
#include "opencv2/legacy.hpp"
|
||||
#include <stdio.h>
|
||||
|
||||
static void help(void)
|
||||
{
|
||||
printf("\nThis program demonstrated color pyramid segmentation cvcvPyrSegmentation() which is controlled\n"
|
||||
"by two trhesholds which can be manipulated by a trackbar. It can take an image file name or defaults to 'fruits.jpg'\n"
|
||||
"Usage :\n"
|
||||
"./pyaramid_segmentation [image_path_filename -- Defaults to fruits.jpg]\n\n"
|
||||
);
|
||||
}
|
||||
|
||||
IplImage* image[2] = { 0, 0 }, *image0 = 0, *image1 = 0;
|
||||
CvSize size;
|
||||
|
||||
int w0, h0,i;
|
||||
int threshold1, threshold2;
|
||||
int l,level = 4;
|
||||
int sthreshold1, sthreshold2;
|
||||
int l_comp;
|
||||
int block_size = 1000;
|
||||
float parameter;
|
||||
double threshold;
|
||||
double rezult, min_rezult;
|
||||
int filter = CV_GAUSSIAN_5x5;
|
||||
CvConnectedComp *cur_comp, min_comp;
|
||||
CvSeq *comp;
|
||||
CvMemStorage *storage;
|
||||
|
||||
CvPoint pt1, pt2;
|
||||
|
||||
static void ON_SEGMENT(int a)
|
||||
{
|
||||
(void)a;
|
||||
cvPyrSegmentation(image0, image1, storage, &comp,
|
||||
level, threshold1+1, threshold2+1);
|
||||
|
||||
cvShowImage("Segmentation", image1);
|
||||
}
|
||||
|
||||
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
char* filename;
|
||||
|
||||
help();
|
||||
|
||||
filename = argc == 2 ? argv[1] : (char*)"fruits.jpg";
|
||||
|
||||
if( (image[0] = cvLoadImage( filename, 1)) == 0 )
|
||||
{
|
||||
help();
|
||||
printf("Cannot load fileimage - %s\n", filename);
|
||||
return -1;
|
||||
}
|
||||
|
||||
cvNamedWindow("Source", 0);
|
||||
cvShowImage("Source", image[0]);
|
||||
|
||||
cvNamedWindow("Segmentation", 0);
|
||||
|
||||
storage = cvCreateMemStorage ( block_size );
|
||||
|
||||
image[0]->width &= -(1<<level);
|
||||
image[0]->height &= -(1<<level);
|
||||
|
||||
image0 = cvCloneImage( image[0] );
|
||||
image1 = cvCloneImage( image[0] );
|
||||
// segmentation of the color image
|
||||
l = 1;
|
||||
threshold1 =255;
|
||||
threshold2 =30;
|
||||
|
||||
ON_SEGMENT(1);
|
||||
|
||||
sthreshold1 = cvCreateTrackbar("Threshold1", "Segmentation", &threshold1, 255, ON_SEGMENT);
|
||||
sthreshold2 = cvCreateTrackbar("Threshold2", "Segmentation", &threshold2, 255, ON_SEGMENT);
|
||||
|
||||
cvShowImage("Segmentation", image1);
|
||||
cvWaitKey(0);
|
||||
|
||||
cvDestroyWindow("Segmentation");
|
||||
cvDestroyWindow("Source");
|
||||
|
||||
cvReleaseMemStorage(&storage );
|
||||
|
||||
cvReleaseImage(&image[0]);
|
||||
cvReleaseImage(&image0);
|
||||
cvReleaseImage(&image1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef _EiC
|
||||
main(1,"pyramid_segmentation.c");
|
||||
#endif
|
||||
|
Before Width: | Height: | Size: 29 KiB |
@@ -3,9 +3,9 @@
|
||||
#
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
SET(OPENCV_CPP_SAMPLES_REQUIRED_DEPS opencv_core opencv_flann opencv_imgproc
|
||||
opencv_highgui opencv_ml opencv_video opencv_objdetect opencv_photo opencv_nonfree opencv_softcascade
|
||||
opencv_features2d opencv_calib3d opencv_legacy opencv_contrib opencv_stitching opencv_videostab opencv_shape)
|
||||
SET(OPENCV_CPP_SAMPLES_REQUIRED_DEPS opencv_core opencv_imgproc opencv_flann
|
||||
opencv_highgui opencv_ml opencv_video opencv_objdetect opencv_photo opencv_nonfree
|
||||
opencv_features2d opencv_calib3d opencv_stitching opencv_videostab opencv_shape)
|
||||
|
||||
ocv_check_dependencies(${OPENCV_CPP_SAMPLES_REQUIRED_DEPS})
|
||||
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
#http://www.cmake.org/cmake/help/cmake2.6docs.html
|
||||
cmake_minimum_required (VERSION 2.6)
|
||||
project (OpenGL_Qt_Binding)
|
||||
|
||||
|
||||
FIND_PACKAGE( OpenCV REQUIRED )
|
||||
find_package (OpenGL REQUIRED)
|
||||
|
||||
|
||||
ADD_EXECUTABLE(OpenGL_Qt_Binding qt_opengl.cpp)
|
||||
TARGET_LINK_LIBRARIES(OpenGL_Qt_Binding ${OpenCV_LIBS} ${OPENGL_LIBRARIES} )
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cube4.avi ${CMAKE_CURRENT_BINARY_DIR}/cube4.avi COPYONLY)
|
||||
@@ -1,269 +0,0 @@
|
||||
// Yannick Verdie 2010
|
||||
// --- Please read help() below: ---
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
#include <opencv2/calib3d/calib3d.hpp>
|
||||
#include <opencv2/calib3d/calib3d_c.h>
|
||||
#include <opencv2/core/core.hpp>
|
||||
#include <opencv2/highgui/highgui.hpp>
|
||||
#include <opencv2/imgproc/imgproc.hpp>
|
||||
#include <opencv2/legacy/compat.hpp>
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <OpenGL/gl.h>
|
||||
#else
|
||||
#include <GL/gl.h>
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
|
||||
static void help()
|
||||
{
|
||||
cout << "This demo demonstrates the use of the Qt enhanced version of the highgui GUI interface\n"
|
||||
"and dang if it doesn't throw in the use of of the POSIT 3D tracking algorithm too\n"
|
||||
"It works off of the video: cube4.avi\n"
|
||||
"Using OpenCV version " << CV_VERSION << "\n\n"
|
||||
|
||||
" 1) This demo is mainly based on work from Javier Barandiaran Martirena\n"
|
||||
" See this page http://code.opencv.org/projects/opencv/wiki/Posit.\n"
|
||||
" 2) This is a demo to illustrate how to use **OpenGL Callback**.\n"
|
||||
" 3) You need Qt binding to compile this sample with OpenGL support enabled.\n"
|
||||
" 4) The features' detection is very basic and could highly be improved\n"
|
||||
" (basic thresholding tuned for the specific video) but 2).\n"
|
||||
" 5) Thanks to Google Summer of Code 2010 for supporting this work!\n" << endl;
|
||||
}
|
||||
|
||||
#define FOCAL_LENGTH 600
|
||||
#define CUBE_SIZE 0.5
|
||||
|
||||
static void renderCube(float size)
|
||||
{
|
||||
glBegin(GL_QUADS);
|
||||
// Front Face
|
||||
glNormal3f( 0.0f, 0.0f, 1.0f);
|
||||
glVertex3f( 0.0f, 0.0f, 0.0f);
|
||||
glVertex3f( size, 0.0f, 0.0f);
|
||||
glVertex3f( size, size, 0.0f);
|
||||
glVertex3f( 0.0f, size, 0.0f);
|
||||
// Back Face
|
||||
glNormal3f( 0.0f, 0.0f,-1.0f);
|
||||
glVertex3f( 0.0f, 0.0f, size);
|
||||
glVertex3f( 0.0f, size, size);
|
||||
glVertex3f( size, size, size);
|
||||
glVertex3f( size, 0.0f, size);
|
||||
// Top Face
|
||||
glNormal3f( 0.0f, 1.0f, 0.0f);
|
||||
glVertex3f( 0.0f, size, 0.0f);
|
||||
glVertex3f( size, size, 0.0f);
|
||||
glVertex3f( size, size, size);
|
||||
glVertex3f( 0.0f, size, size);
|
||||
// Bottom Face
|
||||
glNormal3f( 0.0f,-1.0f, 0.0f);
|
||||
glVertex3f( 0.0f, 0.0f, 0.0f);
|
||||
glVertex3f( 0.0f, 0.0f, size);
|
||||
glVertex3f( size, 0.0f, size);
|
||||
glVertex3f( size, 0.0f, 0.0f);
|
||||
// Right face
|
||||
glNormal3f( 1.0f, 0.0f, 0.0f);
|
||||
glVertex3f( size, 0.0f, 0.0f);
|
||||
glVertex3f( size, 0.0f, size);
|
||||
glVertex3f( size, size, size);
|
||||
glVertex3f( size, size, 0.0f);
|
||||
// Left Face
|
||||
glNormal3f(-1.0f, 0.0f, 0.0f);
|
||||
glVertex3f( 0.0f, 0.0f, 0.0f);
|
||||
glVertex3f( 0.0f, size, 0.0f);
|
||||
glVertex3f( 0.0f, size, size);
|
||||
glVertex3f( 0.0f, 0.0f, size);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
static void on_opengl(void* param)
|
||||
{
|
||||
//Draw the object with the estimated pose
|
||||
glLoadIdentity();
|
||||
glScalef( 1.0f, 1.0f, -1.0f);
|
||||
glMultMatrixf( (float*)param );
|
||||
glEnable( GL_LIGHTING );
|
||||
glEnable( GL_LIGHT0 );
|
||||
glEnable( GL_BLEND );
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||
renderCube( CUBE_SIZE );
|
||||
glDisable(GL_BLEND);
|
||||
glDisable( GL_LIGHTING );
|
||||
}
|
||||
|
||||
static void initPOSIT(std::vector<CvPoint3D32f> * modelPoints)
|
||||
{
|
||||
// Create the model pointss
|
||||
modelPoints->push_back(cvPoint3D32f(0.0f, 0.0f, 0.0f)); // The first must be (0, 0, 0)
|
||||
modelPoints->push_back(cvPoint3D32f(0.0f, 0.0f, CUBE_SIZE));
|
||||
modelPoints->push_back(cvPoint3D32f(CUBE_SIZE, 0.0f, 0.0f));
|
||||
modelPoints->push_back(cvPoint3D32f(0.0f, CUBE_SIZE, 0.0f));
|
||||
}
|
||||
|
||||
static void foundCorners(vector<CvPoint2D32f> * srcImagePoints, const Mat & source, Mat & grayImage)
|
||||
{
|
||||
cvtColor(source, grayImage, COLOR_RGB2GRAY);
|
||||
GaussianBlur(grayImage, grayImage, Size(11, 11), 0, 0);
|
||||
normalize(grayImage, grayImage, 0, 255, NORM_MINMAX);
|
||||
threshold(grayImage, grayImage, 26, 255, THRESH_BINARY_INV); //25
|
||||
|
||||
Mat MgrayImage = grayImage;
|
||||
vector<vector<Point> > contours;
|
||||
vector<Vec4i> hierarchy;
|
||||
findContours(MgrayImage, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
|
||||
|
||||
Point p;
|
||||
vector<CvPoint2D32f> srcImagePoints_temp(4, cvPoint2D32f(0, 0));
|
||||
|
||||
if (contours.size() == srcImagePoints_temp.size())
|
||||
{
|
||||
for (size_t i = 0; i < contours.size(); i++ )
|
||||
{
|
||||
p.x = p.y = 0;
|
||||
|
||||
for (size_t j = 0 ; j < contours[i].size(); j++)
|
||||
p += contours[i][j];
|
||||
|
||||
srcImagePoints_temp.at(i) = cvPoint2D32f(float(p.x) / contours[i].size(), float(p.y) / contours[i].size());
|
||||
}
|
||||
|
||||
// Need to keep the same order
|
||||
// > y = 0
|
||||
// > x = 1
|
||||
// < x = 2
|
||||
// < y = 3
|
||||
|
||||
// get point 0;
|
||||
size_t index = 0;
|
||||
for (size_t i = 1 ; i<srcImagePoints_temp.size(); i++)
|
||||
if (srcImagePoints_temp.at(i).y > srcImagePoints_temp.at(index).y)
|
||||
index = i;
|
||||
srcImagePoints->at(0) = srcImagePoints_temp.at(index);
|
||||
|
||||
// get point 1;
|
||||
index = 0;
|
||||
for (size_t i = 1 ; i<srcImagePoints_temp.size(); i++)
|
||||
if (srcImagePoints_temp.at(i).x > srcImagePoints_temp.at(index).x)
|
||||
index = i;
|
||||
srcImagePoints->at(1) = srcImagePoints_temp.at(index);
|
||||
|
||||
// get point 2;
|
||||
index = 0;
|
||||
for (size_t i = 1 ; i<srcImagePoints_temp.size(); i++)
|
||||
if (srcImagePoints_temp.at(i).x < srcImagePoints_temp.at(index).x)
|
||||
index = i;
|
||||
srcImagePoints->at(2) = srcImagePoints_temp.at(index);
|
||||
|
||||
// get point 3;
|
||||
index = 0;
|
||||
for (size_t i = 1 ; i<srcImagePoints_temp.size(); i++ )
|
||||
if (srcImagePoints_temp.at(i).y < srcImagePoints_temp.at(index).y)
|
||||
index = i;
|
||||
srcImagePoints->at(3) = srcImagePoints_temp.at(index);
|
||||
|
||||
Mat Msource = source;
|
||||
stringstream ss;
|
||||
for (size_t i = 0; i<srcImagePoints_temp.size(); i++ )
|
||||
{
|
||||
ss << i;
|
||||
circle(Msource, srcImagePoints->at(i), 5, Scalar(0, 0, 255));
|
||||
putText(Msource, ss.str(), srcImagePoints->at(i), FONT_HERSHEY_SIMPLEX, 1, Scalar(0, 0, 255));
|
||||
ss.str("");
|
||||
|
||||
// new coordinate system in the middle of the frame and reversed (camera coordinate system)
|
||||
srcImagePoints->at(i) = cvPoint2D32f(srcImagePoints_temp.at(i).x - source.cols / 2,
|
||||
source.rows / 2 - srcImagePoints_temp.at(i).y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void createOpenGLMatrixFrom(float * posePOSIT, const CvMatr32f & rotationMatrix,
|
||||
const CvVect32f & translationVector)
|
||||
{
|
||||
// coordinate system returned is relative to the first 3D input point
|
||||
for (int f = 0; f < 3; f++)
|
||||
for (int c = 0; c < 3; c++)
|
||||
posePOSIT[c * 4 + f] = rotationMatrix[f * 3 + c]; // transposed
|
||||
|
||||
posePOSIT[3] = translationVector[0];
|
||||
posePOSIT[7] = translationVector[1];
|
||||
posePOSIT[11] = translationVector[2];
|
||||
posePOSIT[12] = 0.0f;
|
||||
posePOSIT[13] = 0.0f;
|
||||
posePOSIT[14] = 0.0f;
|
||||
posePOSIT[15] = 1.0f;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
help();
|
||||
|
||||
string fileName = "cube4.avi";
|
||||
VideoCapture video(fileName);
|
||||
if (!video.isOpened())
|
||||
{
|
||||
cerr << "Video file " << fileName << " could not be opened" << endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
Mat source, grayImage;
|
||||
video >> source;
|
||||
|
||||
namedWindow("Original", WINDOW_AUTOSIZE | WINDOW_FREERATIO);
|
||||
namedWindow("POSIT", WINDOW_OPENGL | WINDOW_FREERATIO);
|
||||
resizeWindow("POSIT", source.cols, source.rows);
|
||||
|
||||
displayOverlay("POSIT", "We lost the 4 corners' detection quite often (the red circles disappear).\n"
|
||||
"This demo is only to illustrate how to use OpenGL callback.\n"
|
||||
" -- Press ESC to exit.", 10000);
|
||||
|
||||
float OpenGLMatrix[] = { 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0 };
|
||||
setOpenGlContext("POSIT");
|
||||
setOpenGlDrawCallback("POSIT", on_opengl, OpenGLMatrix);
|
||||
|
||||
vector<CvPoint3D32f> modelPoints;
|
||||
initPOSIT(&modelPoints);
|
||||
|
||||
// Create the POSIT object with the model points
|
||||
CvPOSITObject* positObject = cvCreatePOSITObject( &modelPoints[0], (int)modelPoints.size());
|
||||
|
||||
CvMatr32f rotation_matrix = new float[9];
|
||||
CvVect32f translation_vector = new float[3];
|
||||
CvTermCriteria criteria = cvTermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 100, 1e-4f);
|
||||
vector<CvPoint2D32f> srcImagePoints(4, cvPoint2D32f(0, 0));
|
||||
|
||||
while (waitKey(33) != 27)
|
||||
{
|
||||
video >> source;
|
||||
if (source.empty())
|
||||
break;
|
||||
|
||||
imshow("Original", source);
|
||||
|
||||
foundCorners(&srcImagePoints, source, grayImage);
|
||||
cvPOSIT(positObject, &srcImagePoints[0], FOCAL_LENGTH, criteria, rotation_matrix, translation_vector);
|
||||
createOpenGLMatrixFrom(OpenGLMatrix, rotation_matrix, translation_vector);
|
||||
|
||||
updateWindow("POSIT");
|
||||
|
||||
if (video.get(CAP_PROP_POS_AVI_RATIO) > 0.99)
|
||||
video.set(CAP_PROP_POS_AVI_RATIO, 0);
|
||||
}
|
||||
|
||||
setOpenGlDrawCallback("POSIT", NULL, NULL);
|
||||
destroyAllWindows();
|
||||
cvReleasePOSITObject(&positObject);
|
||||
|
||||
delete[]rotation_matrix;
|
||||
delete[]translation_vector;
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
Before Width: | Height: | Size: 83 KiB After Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
@@ -4,10 +4,6 @@
|
||||
#include "opencv2/features2d/features2d.hpp"
|
||||
#include "opencv2/nonfree/nonfree.hpp"
|
||||
#include "opencv2/ml/ml.hpp"
|
||||
#ifdef HAVE_OPENCV_OCL
|
||||
#define _OCL_SVM_ 1 //select whether using ocl::svm method or not, default is using
|
||||
#include "opencv2/ocl/ocl.hpp"
|
||||
#endif
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
@@ -2378,15 +2374,9 @@ static void setSVMTrainAutoParams( CvParamGrid& c_grid, CvParamGrid& gamma_grid,
|
||||
degree_grid.step = 0;
|
||||
}
|
||||
|
||||
#if defined HAVE_OPENCV_OCL && _OCL_SVM_
|
||||
static void trainSVMClassifier( cv::ocl::CvSVM_OCL& svm, const SVMTrainParamsExt& svmParamsExt, const string& objClassName, VocData& vocData,
|
||||
Ptr<BOWImgDescriptorExtractor>& bowExtractor, const Ptr<FeatureDetector>& fdetector,
|
||||
const string& resPath )
|
||||
#else
|
||||
static void trainSVMClassifier( CvSVM& svm, const SVMTrainParamsExt& svmParamsExt, const string& objClassName, VocData& vocData,
|
||||
Ptr<BOWImgDescriptorExtractor>& bowExtractor, const Ptr<FeatureDetector>& fdetector,
|
||||
const string& resPath )
|
||||
#endif
|
||||
{
|
||||
/* first check if a previously trained svm for the current class has been saved to file */
|
||||
string svmFilename = resPath + svmsDir + "/" + objClassName + ".xml.gz";
|
||||
@@ -2459,15 +2449,9 @@ static void trainSVMClassifier( CvSVM& svm, const SVMTrainParamsExt& svmParamsEx
|
||||
}
|
||||
}
|
||||
|
||||
#if defined HAVE_OPENCV_OCL && _OCL_SVM_
|
||||
static void computeConfidences( cv::ocl::CvSVM_OCL& svm, const string& objClassName, VocData& vocData,
|
||||
Ptr<BOWImgDescriptorExtractor>& bowExtractor, const Ptr<FeatureDetector>& fdetector,
|
||||
const string& resPath )
|
||||
#else
|
||||
static void computeConfidences( CvSVM& svm, const string& objClassName, VocData& vocData,
|
||||
Ptr<BOWImgDescriptorExtractor>& bowExtractor, const Ptr<FeatureDetector>& fdetector,
|
||||
const string& resPath )
|
||||
#endif
|
||||
{
|
||||
cout << "*** CALCULATING CONFIDENCES FOR CLASS " << objClassName << " ***" << endl;
|
||||
cout << "CALCULATING BOW VECTORS FOR TEST SET OF " << objClassName << "..." << endl;
|
||||
@@ -2606,11 +2590,7 @@ int main(int argc, char** argv)
|
||||
for( size_t classIdx = 0; classIdx < objClasses.size(); ++classIdx )
|
||||
{
|
||||
// Train a classifier on train dataset
|
||||
#if defined HAVE_OPENCV_OCL && _OCL_SVM_
|
||||
cv::ocl::CvSVM_OCL svm;
|
||||
#else
|
||||
CvSVM svm;
|
||||
#endif
|
||||
trainSVMClassifier( svm, svmTrainParamsExt, objClasses[classIdx], vocData,
|
||||
bowExtractor, featureDetector, resPath );
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 120 KiB After Width: | Height: | Size: 120 KiB |
@@ -1,131 +0,0 @@
|
||||
/*
|
||||
* matching_test.cpp
|
||||
*
|
||||
* Created on: Oct 17, 2010
|
||||
* Author: ethan
|
||||
*/
|
||||
#include "opencv2/core.hpp"
|
||||
#include <opencv2/core/utility.hpp>
|
||||
#include "opencv2/calib3d.hpp"
|
||||
#include "opencv2/features2d.hpp"
|
||||
#include "opencv2/imgproc.hpp"
|
||||
#include "opencv2/highgui.hpp"
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
||||
using namespace cv;
|
||||
using namespace std;
|
||||
|
||||
//Copy (x,y) location of descriptor matches found from KeyPoint data structures into Point2f vectors
|
||||
static void matches2points(const vector<DMatch>& matches, const vector<KeyPoint>& kpts_train,
|
||||
const vector<KeyPoint>& kpts_query, vector<Point2f>& pts_train, vector<Point2f>& pts_query)
|
||||
{
|
||||
pts_train.clear();
|
||||
pts_query.clear();
|
||||
pts_train.reserve(matches.size());
|
||||
pts_query.reserve(matches.size());
|
||||
for (size_t i = 0; i < matches.size(); i++)
|
||||
{
|
||||
const DMatch& match = matches[i];
|
||||
pts_query.push_back(kpts_query[match.queryIdx].pt);
|
||||
pts_train.push_back(kpts_train[match.trainIdx].pt);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static double match(const vector<KeyPoint>& /*kpts_train*/, const vector<KeyPoint>& /*kpts_query*/, DescriptorMatcher& matcher,
|
||||
const Mat& train, const Mat& query, vector<DMatch>& matches)
|
||||
{
|
||||
|
||||
double t = (double)getTickCount();
|
||||
matcher.match(query, train, matches); //Using features2d
|
||||
return ((double)getTickCount() - t) / getTickFrequency();
|
||||
}
|
||||
|
||||
static void help()
|
||||
{
|
||||
cout << "This program shows how to use BRIEF descriptor to match points in features2d" << endl <<
|
||||
"It takes in two images, finds keypoints and matches them displaying matches and final homography warped results" << endl <<
|
||||
"Usage: " << endl <<
|
||||
"image1 image2 " << endl <<
|
||||
"Example: " << endl <<
|
||||
"box.png box_in_scene.png " << endl;
|
||||
}
|
||||
|
||||
const char* keys =
|
||||
{
|
||||
"{@first_image | box.png | the first image}"
|
||||
"{@second_image | box_in_scene.png | the second image}"
|
||||
};
|
||||
|
||||
int main(int argc, const char ** argv)
|
||||
{
|
||||
|
||||
help();
|
||||
CommandLineParser parser(argc, argv, keys);
|
||||
string im1_name = parser.get<string>(0);
|
||||
string im2_name = parser.get<string>(1);
|
||||
|
||||
Mat im1 = imread(im1_name, IMREAD_GRAYSCALE);
|
||||
Mat im2 = imread(im2_name, IMREAD_GRAYSCALE);
|
||||
|
||||
if (im1.empty() || im2.empty())
|
||||
{
|
||||
cout << "could not open one of the images..." << endl;
|
||||
cout << "the cmd parameters have next current value: " << endl;
|
||||
parser.printMessage();
|
||||
return 1;
|
||||
}
|
||||
|
||||
double t = (double)getTickCount();
|
||||
|
||||
FastFeatureDetector detector(50);
|
||||
BriefDescriptorExtractor extractor(32); //this is really 32 x 8 matches since they are binary matches packed into bytes
|
||||
|
||||
vector<KeyPoint> kpts_1, kpts_2;
|
||||
detector.detect(im1, kpts_1);
|
||||
detector.detect(im2, kpts_2);
|
||||
|
||||
t = ((double)getTickCount() - t) / getTickFrequency();
|
||||
|
||||
cout << "found " << kpts_1.size() << " keypoints in " << im1_name << endl << "fount " << kpts_2.size()
|
||||
<< " keypoints in " << im2_name << endl << "took " << t << " seconds." << endl;
|
||||
|
||||
Mat desc_1, desc_2;
|
||||
|
||||
cout << "computing descriptors..." << endl;
|
||||
|
||||
t = (double)getTickCount();
|
||||
|
||||
extractor.compute(im1, kpts_1, desc_1);
|
||||
extractor.compute(im2, kpts_2, desc_2);
|
||||
|
||||
t = ((double)getTickCount() - t) / getTickFrequency();
|
||||
|
||||
cout << "done computing descriptors... took " << t << " seconds" << endl;
|
||||
|
||||
//Do matching using features2d
|
||||
cout << "matching with BruteForceMatcher<Hamming>" << endl;
|
||||
BFMatcher matcher_popcount(extractor.defaultNorm());
|
||||
vector<DMatch> matches_popcount;
|
||||
double pop_time = match(kpts_1, kpts_2, matcher_popcount, desc_1, desc_2, matches_popcount);
|
||||
cout << "done BruteForceMatcher<Hamming> matching. took " << pop_time << " seconds" << endl;
|
||||
|
||||
vector<Point2f> mpts_1, mpts_2;
|
||||
matches2points(matches_popcount, kpts_1, kpts_2, mpts_1, mpts_2); //Extract a list of the (x,y) location of the matches
|
||||
vector<char> outlier_mask;
|
||||
Mat H = findHomography(mpts_2, mpts_1, RANSAC, 1, outlier_mask);
|
||||
|
||||
Mat outimg;
|
||||
drawMatches(im2, kpts_2, im1, kpts_1, matches_popcount, outimg, Scalar::all(-1), Scalar::all(-1), outlier_mask);
|
||||
imshow("matches - popcount - outliers removed", outimg);
|
||||
|
||||
Mat warped;
|
||||
Mat diff;
|
||||
warpPerspective(im2, warped, H, im1.size());
|
||||
imshow("warped", warped);
|
||||
absdiff(im1,warped,diff);
|
||||
imshow("diff", diff);
|
||||
waitKey();
|
||||
return 0;
|
||||
}
|
||||
@@ -1,778 +0,0 @@
|
||||
#include "opencv2/core.hpp"
|
||||
#include <opencv2/core/utility.hpp>
|
||||
#include "opencv2/imgproc.hpp"
|
||||
#include "opencv2/calib3d.hpp"
|
||||
#include "opencv2/features2d.hpp"
|
||||
#include "opencv2/highgui.hpp"
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
using namespace cv;
|
||||
using namespace std;
|
||||
|
||||
static void help()
|
||||
{
|
||||
printf("\nSigh: This program is not complete/will be replaced. \n"
|
||||
"So: Use this just to see hints of how to use things like Rodrigues\n"
|
||||
" conversions, finding the fundamental matrix, using descriptor\n"
|
||||
" finding and matching in features2d and using camera parameters\n"
|
||||
"Usage: build3dmodel -i <intrinsics_filename>\n"
|
||||
"\t[-d <detector>] [-de <descriptor_extractor>] -m <model_name>\n\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static bool readCameraMatrix(const string& filename,
|
||||
Mat& cameraMatrix, Mat& distCoeffs,
|
||||
Size& calibratedImageSize )
|
||||
{
|
||||
FileStorage fs(filename, FileStorage::READ);
|
||||
fs["image_width"] >> calibratedImageSize.width;
|
||||
fs["image_height"] >> calibratedImageSize.height;
|
||||
fs["distortion_coefficients"] >> distCoeffs;
|
||||
fs["camera_matrix"] >> cameraMatrix;
|
||||
|
||||
if( distCoeffs.type() != CV_64F )
|
||||
distCoeffs = Mat_<double>(distCoeffs);
|
||||
if( cameraMatrix.type() != CV_64F )
|
||||
cameraMatrix = Mat_<double>(cameraMatrix);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool readModelViews( const string& filename, vector<Point3f>& box,
|
||||
vector<string>& imagelist,
|
||||
vector<Rect>& roiList, vector<Vec6f>& poseList )
|
||||
{
|
||||
imagelist.resize(0);
|
||||
roiList.resize(0);
|
||||
poseList.resize(0);
|
||||
box.resize(0);
|
||||
|
||||
FileStorage fs(filename, FileStorage::READ);
|
||||
if( !fs.isOpened() )
|
||||
return false;
|
||||
fs["box"] >> box;
|
||||
|
||||
FileNode all = fs["views"];
|
||||
if( all.type() != FileNode::SEQ )
|
||||
return false;
|
||||
FileNodeIterator it = all.begin(), it_end = all.end();
|
||||
|
||||
for(; it != it_end; ++it)
|
||||
{
|
||||
FileNode n = *it;
|
||||
imagelist.push_back((string)n["image"]);
|
||||
FileNode nr = n["roi"];
|
||||
roiList.push_back(Rect((int)nr[0], (int)nr[1], (int)nr[2], (int)nr[3]));
|
||||
FileNode np = n["pose"];
|
||||
poseList.push_back(Vec6f((float)np[0], (float)np[1], (float)np[2],
|
||||
(float)np[3], (float)np[4], (float)np[5]));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
struct PointModel
|
||||
{
|
||||
vector<Point3f> points;
|
||||
vector<vector<int> > didx;
|
||||
Mat descriptors;
|
||||
string name;
|
||||
};
|
||||
|
||||
|
||||
static void writeModel(const string& modelFileName, const string& modelname,
|
||||
const PointModel& model)
|
||||
{
|
||||
FileStorage fs(modelFileName, FileStorage::WRITE);
|
||||
|
||||
fs << modelname << "{" <<
|
||||
"points" << "[:" << model.points << "]" <<
|
||||
"idx" << "[:";
|
||||
|
||||
for( size_t i = 0; i < model.didx.size(); i++ )
|
||||
fs << "[:" << model.didx[i] << "]";
|
||||
fs << "]" << "descriptors" << model.descriptors;
|
||||
}
|
||||
|
||||
|
||||
static void unpackPose(const Vec6f& pose, Mat& R, Mat& t)
|
||||
{
|
||||
Mat rvec = (Mat_<double>(3,1) << pose[0], pose[1], pose[2]);
|
||||
t = (Mat_<double>(3,1) << pose[3], pose[4], pose[5]);
|
||||
Rodrigues(rvec, R);
|
||||
}
|
||||
|
||||
|
||||
static Mat getFundamentalMat( const Mat& R1, const Mat& t1,
|
||||
const Mat& R2, const Mat& t2,
|
||||
const Mat& cameraMatrix )
|
||||
{
|
||||
Mat_<double> R = R2*R1.t(), t = t2 - R*t1;
|
||||
double tx = t.at<double>(0,0), ty = t.at<double>(1,0), tz = t.at<double>(2,0);
|
||||
Mat E = (Mat_<double>(3,3) << 0, -tz, ty, tz, 0, -tx, -ty, tx, 0)*R;
|
||||
Mat iK = cameraMatrix.inv();
|
||||
Mat F = iK.t()*E*iK;
|
||||
|
||||
#if 0
|
||||
static bool checked = false;
|
||||
if(!checked)
|
||||
{
|
||||
vector<Point3f> objpoints(100);
|
||||
Mat O(objpoints);
|
||||
randu(O, Scalar::all(-10), Scalar::all(10));
|
||||
vector<Point2f> imgpoints1, imgpoints2;
|
||||
projectPoints(Mat(objpoints), R1, t1, cameraMatrix, Mat(), imgpoints1);
|
||||
projectPoints(Mat(objpoints), R2, t2, cameraMatrix, Mat(), imgpoints2);
|
||||
double* f = (double*)F.data;
|
||||
for( size_t i = 0; i < objpoints.size(); i++ )
|
||||
{
|
||||
Point2f p1 = imgpoints1[i], p2 = imgpoints2[i];
|
||||
double diff = p2.x*(f[0]*p1.x + f[1]*p1.y + f[2]) +
|
||||
p2.y*(f[3]*p1.x + f[4]*p1.y + f[5]) +
|
||||
f[6]*p1.x + f[7]*p1.y + f[8];
|
||||
CV_Assert(fabs(diff) < 1e-3);
|
||||
}
|
||||
checked = true;
|
||||
}
|
||||
#endif
|
||||
return F;
|
||||
}
|
||||
|
||||
|
||||
static void findConstrainedCorrespondences(const Mat& _F,
|
||||
const vector<KeyPoint>& keypoints1,
|
||||
const vector<KeyPoint>& keypoints2,
|
||||
const Mat& descriptors1,
|
||||
const Mat& descriptors2,
|
||||
vector<Vec2i>& matches,
|
||||
double eps, double ratio)
|
||||
{
|
||||
float F[9]={0};
|
||||
int dsize = descriptors1.cols;
|
||||
|
||||
Mat Fhdr = Mat(3, 3, CV_32F, F);
|
||||
_F.convertTo(Fhdr, CV_32F);
|
||||
matches.clear();
|
||||
|
||||
for( int i = 0; i < (int)keypoints1.size(); i++ )
|
||||
{
|
||||
Point2f p1 = keypoints1[i].pt;
|
||||
double bestDist1 = DBL_MAX, bestDist2 = DBL_MAX;
|
||||
int bestIdx1 = -1;//, bestIdx2 = -1;
|
||||
const float* d1 = descriptors1.ptr<float>(i);
|
||||
|
||||
for( int j = 0; j < (int)keypoints2.size(); j++ )
|
||||
{
|
||||
Point2f p2 = keypoints2[j].pt;
|
||||
double e = p2.x*(F[0]*p1.x + F[1]*p1.y + F[2]) +
|
||||
p2.y*(F[3]*p1.x + F[4]*p1.y + F[5]) +
|
||||
F[6]*p1.x + F[7]*p1.y + F[8];
|
||||
if( fabs(e) > eps )
|
||||
continue;
|
||||
const float* d2 = descriptors2.ptr<float>(j);
|
||||
double dist = 0;
|
||||
int k = 0;
|
||||
|
||||
for( ; k <= dsize - 8; k += 8 )
|
||||
{
|
||||
float t0 = d1[k] - d2[k], t1 = d1[k+1] - d2[k+1];
|
||||
float t2 = d1[k+2] - d2[k+2], t3 = d1[k+3] - d2[k+3];
|
||||
float t4 = d1[k+4] - d2[k+4], t5 = d1[k+5] - d2[k+5];
|
||||
float t6 = d1[k+6] - d2[k+6], t7 = d1[k+7] - d2[k+7];
|
||||
dist += t0*t0 + t1*t1 + t2*t2 + t3*t3 +
|
||||
t4*t4 + t5*t5 + t6*t6 + t7*t7;
|
||||
|
||||
if( dist >= bestDist2 )
|
||||
break;
|
||||
}
|
||||
|
||||
if( dist < bestDist2 )
|
||||
{
|
||||
for( ; k < dsize; k++ )
|
||||
{
|
||||
float t = d1[k] - d2[k];
|
||||
dist += t*t;
|
||||
}
|
||||
|
||||
if( dist < bestDist1 )
|
||||
{
|
||||
bestDist2 = bestDist1;
|
||||
//bestIdx2 = bestIdx1;
|
||||
bestDist1 = dist;
|
||||
bestIdx1 = (int)j;
|
||||
}
|
||||
else if( dist < bestDist2 )
|
||||
{
|
||||
bestDist2 = dist;
|
||||
//bestIdx2 = (int)j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( bestIdx1 >= 0 && bestDist1 < bestDist2*ratio )
|
||||
{
|
||||
Point2f p2 = keypoints1[bestIdx1].pt;
|
||||
double e = p2.x*(F[0]*p1.x + F[1]*p1.y + F[2]) +
|
||||
p2.y*(F[3]*p1.x + F[4]*p1.y + F[5]) +
|
||||
F[6]*p1.x + F[7]*p1.y + F[8];
|
||||
if( e > eps*0.25 )
|
||||
continue;
|
||||
double threshold = bestDist1/ratio;
|
||||
const float* d22 = descriptors2.ptr<float>(bestIdx1);
|
||||
int i1 = 0;
|
||||
for( ; i1 < (int)keypoints1.size(); i1++ )
|
||||
{
|
||||
if( i1 == i )
|
||||
continue;
|
||||
Point2f pt1 = keypoints1[i1].pt;
|
||||
const float* d11 = descriptors1.ptr<float>(i1);
|
||||
double dist = 0;
|
||||
|
||||
e = p2.x*(F[0]*pt1.x + F[1]*pt1.y + F[2]) +
|
||||
p2.y*(F[3]*pt1.x + F[4]*pt1.y + F[5]) +
|
||||
F[6]*pt1.x + F[7]*pt1.y + F[8];
|
||||
if( fabs(e) > eps )
|
||||
continue;
|
||||
|
||||
for( int k = 0; k < dsize; k++ )
|
||||
{
|
||||
float t = d11[k] - d22[k];
|
||||
dist += t*t;
|
||||
if( dist >= threshold )
|
||||
break;
|
||||
}
|
||||
|
||||
if( dist < threshold )
|
||||
break;
|
||||
}
|
||||
if( i1 == (int)keypoints1.size() )
|
||||
matches.push_back(Vec2i(i,bestIdx1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static Point3f findRayIntersection(Point3f k1, Point3f b1, Point3f k2, Point3f b2)
|
||||
{
|
||||
float a[4], b[2], x[2];
|
||||
a[0] = k1.dot(k1);
|
||||
a[1] = a[2] = -k1.dot(k2);
|
||||
a[3] = k2.dot(k2);
|
||||
b[0] = k1.dot(b2 - b1);
|
||||
b[1] = k2.dot(b1 - b2);
|
||||
Mat_<float> A(2, 2, a), B(2, 1, b), X(2, 1, x);
|
||||
solve(A, B, X);
|
||||
|
||||
float s1 = X.at<float>(0, 0);
|
||||
float s2 = X.at<float>(1, 0);
|
||||
return (k1*s1 + b1 + k2*s2 + b2)*0.5f;
|
||||
}
|
||||
|
||||
|
||||
static Point3f triangulatePoint(const vector<Point2f>& ps,
|
||||
const vector<Mat>& Rs,
|
||||
const vector<Mat>& ts,
|
||||
const Mat& cameraMatrix)
|
||||
{
|
||||
Mat_<double> K(cameraMatrix);
|
||||
|
||||
/*if( ps.size() > 2 )
|
||||
{
|
||||
Mat_<double> L(ps.size()*3, 4), U, evalues;
|
||||
Mat_<double> P(3,4), Rt(3,4), Rt_part1=Rt.colRange(0,3), Rt_part2=Rt.colRange(3,4);
|
||||
|
||||
for( size_t i = 0; i < ps.size(); i++ )
|
||||
{
|
||||
double x = ps[i].x, y = ps[i].y;
|
||||
Rs[i].convertTo(Rt_part1, Rt_part1.type());
|
||||
ts[i].convertTo(Rt_part2, Rt_part2.type());
|
||||
P = K*Rt;
|
||||
|
||||
for( int k = 0; k < 4; k++ )
|
||||
{
|
||||
L(i*3, k) = x*P(2,k) - P(0,k);
|
||||
L(i*3+1, k) = y*P(2,k) - P(1,k);
|
||||
L(i*3+2, k) = x*P(1,k) - y*P(0,k);
|
||||
}
|
||||
}
|
||||
|
||||
eigen(L.t()*L, evalues, U);
|
||||
CV_Assert(evalues(0,0) >= evalues(3,0));
|
||||
|
||||
double W = fabs(U(3,3)) > FLT_EPSILON ? 1./U(3,3) : 0;
|
||||
return Point3f((float)(U(3,0)*W), (float)(U(3,1)*W), (float)(U(3,2)*W));
|
||||
}
|
||||
else*/
|
||||
{
|
||||
Mat_<float> iK = K.inv();
|
||||
Mat_<float> R1t = Mat_<float>(Rs[0]).t();
|
||||
Mat_<float> R2t = Mat_<float>(Rs[1]).t();
|
||||
Mat_<float> m1 = (Mat_<float>(3,1) << ps[0].x, ps[0].y, 1);
|
||||
Mat_<float> m2 = (Mat_<float>(3,1) << ps[1].x, ps[1].y, 1);
|
||||
Mat_<float> K1 = R1t*(iK*m1), K2 = R2t*(iK*m2);
|
||||
Mat_<float> B1 = -R1t*Mat_<float>(ts[0]);
|
||||
Mat_<float> B2 = -R2t*Mat_<float>(ts[1]);
|
||||
return findRayIntersection(*K1.ptr<Point3f>(), *B1.ptr<Point3f>(),
|
||||
*K2.ptr<Point3f>(), *B2.ptr<Point3f>());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void triangulatePoint_test(void)
|
||||
{
|
||||
int i, n = 100;
|
||||
vector<Point3f> objpt(n), delta1(n), delta2(n);
|
||||
Mat rvec1(3,1,CV_32F), tvec1(3,1,CV_64F);
|
||||
Mat rvec2(3,1,CV_32F), tvec2(3,1,CV_64F);
|
||||
Mat objptmat(objpt), deltamat1(delta1), deltamat2(delta2);
|
||||
randu(rvec1, Scalar::all(-10), Scalar::all(10));
|
||||
randu(tvec1, Scalar::all(-10), Scalar::all(10));
|
||||
randu(rvec2, Scalar::all(-10), Scalar::all(10));
|
||||
randu(tvec2, Scalar::all(-10), Scalar::all(10));
|
||||
|
||||
randu(objptmat, Scalar::all(-10), Scalar::all(10));
|
||||
double eps = 1e-2;
|
||||
randu(deltamat1, Scalar::all(-eps), Scalar::all(eps));
|
||||
randu(deltamat2, Scalar::all(-eps), Scalar::all(eps));
|
||||
vector<Point2f> imgpt1, imgpt2;
|
||||
Mat_<float> cameraMatrix(3,3);
|
||||
double fx = 1000., fy = 1010., cx = 400.5, cy = 300.5;
|
||||
cameraMatrix << fx, 0, cx, 0, fy, cy, 0, 0, 1;
|
||||
|
||||
projectPoints(Mat(objpt)+Mat(delta1), rvec1, tvec1, cameraMatrix, Mat(), imgpt1);
|
||||
projectPoints(Mat(objpt)+Mat(delta2), rvec2, tvec2, cameraMatrix, Mat(), imgpt2);
|
||||
|
||||
vector<Point3f> objptt(n);
|
||||
vector<Point2f> pts(2);
|
||||
vector<Mat> Rv(2), tv(2);
|
||||
Rodrigues(rvec1, Rv[0]);
|
||||
Rodrigues(rvec2, Rv[1]);
|
||||
tv[0] = tvec1; tv[1] = tvec2;
|
||||
for( i = 0; i < n; i++ )
|
||||
{
|
||||
pts[0] = imgpt1[i]; pts[1] = imgpt2[i];
|
||||
objptt[i] = triangulatePoint(pts, Rv, tv, cameraMatrix);
|
||||
}
|
||||
double err = norm(Mat(objpt), Mat(objptt), NORM_INF);
|
||||
CV_Assert(err < 1e-1);
|
||||
}
|
||||
|
||||
typedef pair<int, int> Pair2i;
|
||||
typedef map<Pair2i, int> Set2i;
|
||||
|
||||
struct EqKeypoints
|
||||
{
|
||||
EqKeypoints(const vector<int>* _dstart, const Set2i* _pairs)
|
||||
: dstart(_dstart), pairs(_pairs) {}
|
||||
|
||||
bool operator()(const Pair2i& a, const Pair2i& b) const
|
||||
{
|
||||
return pairs->find(Pair2i(dstart->at(a.first) + a.second,
|
||||
dstart->at(b.first) + b.second)) != pairs->end();
|
||||
}
|
||||
|
||||
const vector<int>* dstart;
|
||||
const Set2i* pairs;
|
||||
};
|
||||
|
||||
template<typename _Tp, class _EqPredicate> static
|
||||
int partition( const std::vector<_Tp>& _vec, std::vector<int>& labels,
|
||||
_EqPredicate predicate=_EqPredicate())
|
||||
{
|
||||
int i, j, N = (int)_vec.size();
|
||||
const _Tp* vec = &_vec[0];
|
||||
|
||||
const int PARENT=0;
|
||||
const int RANK=1;
|
||||
|
||||
std::vector<int> _nodes(N*2);
|
||||
int (*nodes)[2] = (int(*)[2])&_nodes[0];
|
||||
|
||||
// The first O(N) pass: create N single-vertex trees
|
||||
for(i = 0; i < N; i++)
|
||||
{
|
||||
nodes[i][PARENT]=-1;
|
||||
nodes[i][RANK] = 0;
|
||||
}
|
||||
|
||||
// The main O(N^2) pass: merge connected components
|
||||
for( i = 0; i < N; i++ )
|
||||
{
|
||||
int root = i;
|
||||
|
||||
// find root
|
||||
while( nodes[root][PARENT] >= 0 )
|
||||
root = nodes[root][PARENT];
|
||||
|
||||
for( j = 0; j < N; j++ )
|
||||
{
|
||||
if( i == j || !predicate(vec[i], vec[j]))
|
||||
continue;
|
||||
int root2 = j;
|
||||
|
||||
while( nodes[root2][PARENT] >= 0 )
|
||||
root2 = nodes[root2][PARENT];
|
||||
|
||||
if( root2 != root )
|
||||
{
|
||||
// unite both trees
|
||||
int rank = nodes[root][RANK], rank2 = nodes[root2][RANK];
|
||||
if( rank > rank2 )
|
||||
nodes[root2][PARENT] = root;
|
||||
else
|
||||
{
|
||||
nodes[root][PARENT] = root2;
|
||||
nodes[root2][RANK] += rank == rank2;
|
||||
root = root2;
|
||||
}
|
||||
CV_Assert( nodes[root][PARENT] < 0 );
|
||||
|
||||
int k = j, parent;
|
||||
|
||||
// compress the path from node2 to root
|
||||
while( (parent = nodes[k][PARENT]) >= 0 )
|
||||
{
|
||||
nodes[k][PARENT] = root;
|
||||
k = parent;
|
||||
}
|
||||
|
||||
// compress the path from node to root
|
||||
k = i;
|
||||
while( (parent = nodes[k][PARENT]) >= 0 )
|
||||
{
|
||||
nodes[k][PARENT] = root;
|
||||
k = parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Final O(N) pass: enumerate classes
|
||||
labels.resize(N);
|
||||
int nclasses = 0;
|
||||
|
||||
for( i = 0; i < N; i++ )
|
||||
{
|
||||
int root = i;
|
||||
while( nodes[root][PARENT] >= 0 )
|
||||
root = nodes[root][PARENT];
|
||||
// re-use the rank as the class label
|
||||
if( nodes[root][RANK] >= 0 )
|
||||
nodes[root][RANK] = ~nclasses++;
|
||||
labels[i] = ~nodes[root][RANK];
|
||||
}
|
||||
|
||||
return nclasses;
|
||||
}
|
||||
|
||||
static void build3dmodel( const Ptr<FeatureDetector>& detector,
|
||||
const Ptr<DescriptorExtractor>& descriptorExtractor,
|
||||
const vector<Point3f>& /*modelBox*/,
|
||||
const vector<string>& imageList,
|
||||
const vector<Rect>& roiList,
|
||||
const vector<Vec6f>& poseList,
|
||||
const Mat& cameraMatrix,
|
||||
PointModel& model )
|
||||
{
|
||||
int progressBarSize = 10;
|
||||
|
||||
const double Feps = 5;
|
||||
const double DescriptorRatio = 0.7;
|
||||
|
||||
vector<vector<KeyPoint> > allkeypoints;
|
||||
vector<int> dstart;
|
||||
vector<float> alldescriptorsVec;
|
||||
vector<Vec2i> pairwiseMatches;
|
||||
vector<Mat> Rs, ts;
|
||||
int descriptorSize = 0;
|
||||
Mat descriptorbuf;
|
||||
Set2i pairs, keypointsIdxMap;
|
||||
|
||||
model.points.clear();
|
||||
model.didx.clear();
|
||||
|
||||
dstart.push_back(0);
|
||||
|
||||
size_t nimages = imageList.size();
|
||||
size_t nimagePairs = (nimages - 1)*nimages/2 - nimages;
|
||||
|
||||
printf("\nComputing descriptors ");
|
||||
|
||||
// 1. find all the keypoints and all the descriptors
|
||||
for( size_t i = 0; i < nimages; i++ )
|
||||
{
|
||||
Mat img = imread(imageList[i], 1), gray;
|
||||
cvtColor(img, gray, COLOR_BGR2GRAY);
|
||||
|
||||
vector<KeyPoint> keypoints;
|
||||
detector->detect(gray, keypoints);
|
||||
descriptorExtractor->compute(gray, keypoints, descriptorbuf);
|
||||
Point2f roiofs = roiList[i].tl();
|
||||
for( size_t k = 0; k < keypoints.size(); k++ )
|
||||
keypoints[k].pt += roiofs;
|
||||
allkeypoints.push_back(keypoints);
|
||||
|
||||
Mat buf = descriptorbuf;
|
||||
if( !buf.isContinuous() || buf.type() != CV_32F )
|
||||
{
|
||||
buf.release();
|
||||
descriptorbuf.convertTo(buf, CV_32F);
|
||||
}
|
||||
descriptorSize = buf.cols;
|
||||
|
||||
size_t prev = alldescriptorsVec.size();
|
||||
size_t delta = buf.rows*buf.cols;
|
||||
alldescriptorsVec.resize(prev + delta);
|
||||
std::copy(buf.ptr<float>(), buf.ptr<float>() + delta,
|
||||
alldescriptorsVec.begin() + prev);
|
||||
dstart.push_back(dstart.back() + (int)keypoints.size());
|
||||
|
||||
Mat R, t;
|
||||
unpackPose(poseList[i], R, t);
|
||||
Rs.push_back(R);
|
||||
ts.push_back(t);
|
||||
|
||||
if( (i+1)*progressBarSize/nimages > i*progressBarSize/nimages )
|
||||
{
|
||||
putchar('.');
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
Mat alldescriptors((int)alldescriptorsVec.size()/descriptorSize, descriptorSize, CV_32F,
|
||||
&alldescriptorsVec[0]);
|
||||
|
||||
printf("\nOk. total images = %d. total keypoints = %d\n",
|
||||
(int)nimages, alldescriptors.rows);
|
||||
|
||||
printf("\nFinding correspondences ");
|
||||
|
||||
int pairsFound = 0;
|
||||
|
||||
vector<Point2f> pts_k(2);
|
||||
vector<Mat> Rs_k(2), ts_k(2);
|
||||
//namedWindow("img1", 1);
|
||||
//namedWindow("img2", 1);
|
||||
|
||||
// 2. find pairwise correspondences
|
||||
for( size_t i = 0; i < nimages; i++ )
|
||||
for( size_t j = i+1; j < nimages; j++ )
|
||||
{
|
||||
const vector<KeyPoint>& keypoints1 = allkeypoints[i];
|
||||
const vector<KeyPoint>& keypoints2 = allkeypoints[j];
|
||||
Mat descriptors1 = alldescriptors.rowRange(dstart[i], dstart[i+1]);
|
||||
Mat descriptors2 = alldescriptors.rowRange(dstart[j], dstart[j+1]);
|
||||
|
||||
Mat F = getFundamentalMat(Rs[i], ts[i], Rs[j], ts[j], cameraMatrix);
|
||||
|
||||
findConstrainedCorrespondences( F, keypoints1, keypoints2,
|
||||
descriptors1, descriptors2,
|
||||
pairwiseMatches, Feps, DescriptorRatio );
|
||||
|
||||
//pairsFound += (int)pairwiseMatches.size();
|
||||
|
||||
//Mat img1 = imread(format("%s/frame%04d.jpg", model.name.c_str(), (int)i), 1);
|
||||
//Mat img2 = imread(format("%s/frame%04d.jpg", model.name.c_str(), (int)j), 1);
|
||||
|
||||
//double avg_err = 0;
|
||||
for( size_t k = 0; k < pairwiseMatches.size(); k++ )
|
||||
{
|
||||
int i1 = pairwiseMatches[k][0], i2 = pairwiseMatches[k][1];
|
||||
|
||||
pts_k[0] = keypoints1[i1].pt;
|
||||
pts_k[1] = keypoints2[i2].pt;
|
||||
Rs_k[0] = Rs[i]; Rs_k[1] = Rs[j];
|
||||
ts_k[0] = ts[i]; ts_k[1] = ts[j];
|
||||
Point3f objpt = triangulatePoint(pts_k, Rs_k, ts_k, cameraMatrix);
|
||||
|
||||
vector<Point3f> objpts;
|
||||
objpts.push_back(objpt);
|
||||
vector<Point2f> imgpts1, imgpts2;
|
||||
projectPoints(Mat(objpts), Rs_k[0], ts_k[0], cameraMatrix, Mat(), imgpts1);
|
||||
projectPoints(Mat(objpts), Rs_k[1], ts_k[1], cameraMatrix, Mat(), imgpts2);
|
||||
|
||||
double e1 = norm(imgpts1[0] - keypoints1[i1].pt);
|
||||
double e2 = norm(imgpts2[0] - keypoints2[i2].pt);
|
||||
if( e1 + e2 > 5 )
|
||||
continue;
|
||||
|
||||
pairsFound++;
|
||||
|
||||
//model.points.push_back(objpt);
|
||||
pairs[Pair2i(i1+dstart[i], i2+dstart[j])] = 1;
|
||||
pairs[Pair2i(i2+dstart[j], i1+dstart[i])] = 1;
|
||||
keypointsIdxMap[Pair2i((int)i,i1)] = 1;
|
||||
keypointsIdxMap[Pair2i((int)j,i2)] = 1;
|
||||
//CV_Assert(e1 < 5 && e2 < 5);
|
||||
//Scalar color(rand()%256,rand()%256, rand()%256);
|
||||
//circle(img1, keypoints1[i1].pt, 2, color, -1, CV_AA);
|
||||
//circle(img2, keypoints2[i2].pt, 2, color, -1, CV_AA);
|
||||
}
|
||||
//printf("avg err = %g\n", pairwiseMatches.size() ? avg_err/(2*pairwiseMatches.size()) : 0.);
|
||||
//imshow("img1", img1);
|
||||
//imshow("img2", img2);
|
||||
//waitKey();
|
||||
|
||||
if( (i+1)*progressBarSize/nimagePairs > i*progressBarSize/nimagePairs )
|
||||
{
|
||||
putchar('.');
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
printf("\nOk. Total pairs = %d\n", pairsFound );
|
||||
|
||||
// 3. build the keypoint clusters
|
||||
vector<Pair2i> keypointsIdx;
|
||||
Set2i::iterator kpidx_it = keypointsIdxMap.begin(), kpidx_end = keypointsIdxMap.end();
|
||||
|
||||
for( ; kpidx_it != kpidx_end; ++kpidx_it )
|
||||
keypointsIdx.push_back(kpidx_it->first);
|
||||
|
||||
printf("\nClustering correspondences ");
|
||||
|
||||
vector<int> labels;
|
||||
int nclasses = partition( keypointsIdx, labels, EqKeypoints(&dstart, &pairs) );
|
||||
|
||||
printf("\nOk. Total classes (i.e. 3d points) = %d\n", nclasses );
|
||||
|
||||
model.descriptors.create((int)keypointsIdx.size(), descriptorSize, CV_32F);
|
||||
model.didx.resize(nclasses);
|
||||
model.points.resize(nclasses);
|
||||
|
||||
vector<vector<Pair2i> > clusters(nclasses);
|
||||
for( size_t i = 0; i < keypointsIdx.size(); i++ )
|
||||
clusters[labels[i]].push_back(keypointsIdx[i]);
|
||||
|
||||
// 4. now compute 3D points corresponding to each cluster and fill in the model data
|
||||
printf("\nComputing 3D coordinates ");
|
||||
|
||||
int globalDIdx = 0;
|
||||
for( int k = 0; k < nclasses; k++ )
|
||||
{
|
||||
int i, n = (int)clusters[k].size();
|
||||
pts_k.resize(n);
|
||||
Rs_k.resize(n);
|
||||
ts_k.resize(n);
|
||||
model.didx[k].resize(n);
|
||||
for( i = 0; i < n; i++ )
|
||||
{
|
||||
int imgidx = clusters[k][i].first, ptidx = clusters[k][i].second;
|
||||
Mat dstrow = model.descriptors.row(globalDIdx);
|
||||
alldescriptors.row(dstart[imgidx] + ptidx).copyTo(dstrow);
|
||||
|
||||
model.didx[k][i] = globalDIdx++;
|
||||
pts_k[i] = allkeypoints[imgidx][ptidx].pt;
|
||||
Rs_k[i] = Rs[imgidx];
|
||||
ts_k[i] = ts[imgidx];
|
||||
}
|
||||
Point3f objpt = triangulatePoint(pts_k, Rs_k, ts_k, cameraMatrix);
|
||||
model.points[k] = objpt;
|
||||
|
||||
if( (i+1)*progressBarSize/nclasses > i*progressBarSize/nclasses )
|
||||
{
|
||||
putchar('.');
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
Mat img(768, 1024, CV_8UC3);
|
||||
vector<Point2f> imagePoints;
|
||||
namedWindow("Test", 1);
|
||||
|
||||
// visualize the cloud
|
||||
for( size_t i = 0; i < nimages; i++ )
|
||||
{
|
||||
img = imread(format("%s/frame%04d.jpg", model.name.c_str(), (int)i), 1);
|
||||
projectPoints(Mat(model.points), Rs[i], ts[i], cameraMatrix, Mat(), imagePoints);
|
||||
|
||||
for( int k = 0; k < (int)imagePoints.size(); k++ )
|
||||
circle(img, imagePoints[k], 2, Scalar(0,255,0), -1, LINE_AA, 0);
|
||||
|
||||
imshow("Test", img);
|
||||
int c = waitKey();
|
||||
if( c == 'q' || c == 'Q' )
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
const char* intrinsicsFilename = 0;
|
||||
const char* modelName = 0;
|
||||
const char* detectorName = "SURF";
|
||||
const char* descriptorExtractorName = "SURF";
|
||||
|
||||
vector<Point3f> modelBox;
|
||||
vector<string> imageList;
|
||||
vector<Rect> roiList;
|
||||
vector<Vec6f> poseList;
|
||||
|
||||
if(argc < 3)
|
||||
{
|
||||
help();
|
||||
return -1;
|
||||
}
|
||||
|
||||
for( int i = 1; i < argc; i++ )
|
||||
{
|
||||
if( strcmp(argv[i], "-i") == 0 )
|
||||
intrinsicsFilename = argv[++i];
|
||||
else if( strcmp(argv[i], "-m") == 0 )
|
||||
modelName = argv[++i];
|
||||
else if( strcmp(argv[i], "-d") == 0 )
|
||||
detectorName = argv[++i];
|
||||
else if( strcmp(argv[i], "-de") == 0 )
|
||||
descriptorExtractorName = argv[++i];
|
||||
else
|
||||
{
|
||||
help();
|
||||
printf("Incorrect option\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if( !intrinsicsFilename || !modelName )
|
||||
{
|
||||
printf("Some of the required parameters are missing\n");
|
||||
help();
|
||||
return -1;
|
||||
}
|
||||
|
||||
triangulatePoint_test();
|
||||
|
||||
Mat cameraMatrix, distCoeffs;
|
||||
Size calibratedImageSize;
|
||||
readCameraMatrix(intrinsicsFilename, cameraMatrix, distCoeffs, calibratedImageSize);
|
||||
|
||||
Ptr<FeatureDetector> detector = FeatureDetector::create(detectorName);
|
||||
Ptr<DescriptorExtractor> descriptorExtractor = DescriptorExtractor::create(descriptorExtractorName);
|
||||
|
||||
string modelIndexFilename = format("%s_segm/frame_index.yml", modelName);
|
||||
if(!readModelViews( modelIndexFilename, modelBox, imageList, roiList, poseList))
|
||||
{
|
||||
printf("Can not read the model. Check the parameters and the working directory\n");
|
||||
help();
|
||||
return -1;
|
||||
}
|
||||
|
||||
PointModel model;
|
||||
model.name = modelName;
|
||||
build3dmodel( detector, descriptorExtractor, modelBox,
|
||||
imageList, roiList, poseList, cameraMatrix, model );
|
||||
string outputModelName = format("%s_model.yml.gz", modelName);
|
||||
|
||||
|
||||
printf("\nDone! Now saving the model ...\n");
|
||||
writeModel(outputModelName, modelName, model);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,334 +0,0 @@
|
||||
#include "opencv2/calib3d/calib3d.hpp"
|
||||
#include "opencv2/imgproc/imgproc.hpp"
|
||||
#include "opencv2/highgui/highgui.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <stdio.h>
|
||||
|
||||
using namespace cv;
|
||||
using namespace std;
|
||||
|
||||
static void help()
|
||||
{
|
||||
printf( "\nThis code generates an artificial camera and artificial chessboard images,\n"
|
||||
"and then calibrates. It is basically test code for calibration that shows\n"
|
||||
"how to package calibration points and then calibrate the camera.\n"
|
||||
"Usage:\n"
|
||||
"./calibration_artificial\n\n");
|
||||
}
|
||||
namespace cv
|
||||
{
|
||||
|
||||
/* copy of class defines int tests/cv/chessboardgenerator.h */
|
||||
class ChessBoardGenerator
|
||||
{
|
||||
public:
|
||||
double sensorWidth;
|
||||
double sensorHeight;
|
||||
size_t squareEdgePointsNum;
|
||||
double min_cos;
|
||||
mutable double cov;
|
||||
Size patternSize;
|
||||
int rendererResolutionMultiplier;
|
||||
|
||||
ChessBoardGenerator(const Size& patternSize = Size(8, 6));
|
||||
Mat operator()(const Mat& bg, const Mat& camMat, const Mat& distCoeffs, vector<Point2f>& corners) const;
|
||||
Size cornersSize() const;
|
||||
private:
|
||||
void generateEdge(const Point3f& p1, const Point3f& p2, vector<Point3f>& out) const;
|
||||
Mat generageChessBoard(const Mat& bg, const Mat& camMat, const Mat& distCoeffs,
|
||||
const Point3f& zero, const Point3f& pb1, const Point3f& pb2,
|
||||
float sqWidth, float sqHeight, const vector<Point3f>& whole, vector<Point2f>& corners) const;
|
||||
void generateBasis(Point3f& pb1, Point3f& pb2) const;
|
||||
Point3f generateChessBoardCenter(const Mat& camMat, const Size& imgSize) const;
|
||||
Mat rvec, tvec;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
const Size imgSize(800, 600);
|
||||
const Size brdSize(8, 7);
|
||||
const size_t brds_num = 20;
|
||||
|
||||
template<class T> ostream& operator<<(ostream& out, const Mat_<T>& mat)
|
||||
{
|
||||
for(int j = 0; j < mat.rows; ++j)
|
||||
for(int i = 0; i < mat.cols; ++i)
|
||||
out << mat(j, i) << " ";
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
help();
|
||||
cout << "Initializing background...";
|
||||
Mat background(imgSize, CV_8UC3);
|
||||
randu(background, Scalar::all(32), Scalar::all(255));
|
||||
GaussianBlur(background, background, Size(5, 5), 2);
|
||||
cout << "Done" << endl;
|
||||
|
||||
cout << "Initializing chess board generator...";
|
||||
ChessBoardGenerator cbg(brdSize);
|
||||
cbg.rendererResolutionMultiplier = 4;
|
||||
cout << "Done" << endl;
|
||||
|
||||
/* camera params */
|
||||
Mat_<double> camMat(3, 3);
|
||||
camMat << 300., 0., background.cols/2., 0, 300., background.rows/2., 0., 0., 1.;
|
||||
|
||||
Mat_<double> distCoeffs(1, 5);
|
||||
distCoeffs << 1.2, 0.2, 0., 0., 0.;
|
||||
|
||||
cout << "Generating chessboards...";
|
||||
vector<Mat> boards(brds_num);
|
||||
vector<Point2f> tmp;
|
||||
for(size_t i = 0; i < brds_num; ++i)
|
||||
cout << (boards[i] = cbg(background, camMat, distCoeffs, tmp), i) << " ";
|
||||
cout << "Done" << endl;
|
||||
|
||||
vector<Point3f> chessboard3D;
|
||||
for(int j = 0; j < cbg.cornersSize().height; ++j)
|
||||
for(int i = 0; i < cbg.cornersSize().width; ++i)
|
||||
chessboard3D.push_back(Point3i(i, j, 0));
|
||||
|
||||
/* init points */
|
||||
vector< vector<Point3f> > objectPoints;
|
||||
vector< vector<Point2f> > imagePoints;
|
||||
|
||||
cout << endl << "Finding chessboards' corners...";
|
||||
for(size_t i = 0; i < brds_num; ++i)
|
||||
{
|
||||
cout << i;
|
||||
namedWindow("Current chessboard"); imshow("Current chessboard", boards[i]); waitKey(100);
|
||||
bool found = findChessboardCorners(boards[i], cbg.cornersSize(), tmp);
|
||||
if (found)
|
||||
{
|
||||
imagePoints.push_back(tmp);
|
||||
objectPoints.push_back(chessboard3D);
|
||||
cout<< "-found ";
|
||||
}
|
||||
else
|
||||
cout<< "-not-found ";
|
||||
|
||||
drawChessboardCorners(boards[i], cbg.cornersSize(), Mat(tmp), found);
|
||||
imshow("Current chessboard", boards[i]); waitKey(1000);
|
||||
}
|
||||
cout << "Done" << endl;
|
||||
destroyAllWindows();
|
||||
|
||||
Mat camMat_est;
|
||||
Mat distCoeffs_est;
|
||||
vector<Mat> rvecs, tvecs;
|
||||
|
||||
cout << "Calibrating...";
|
||||
double rep_err = calibrateCamera(objectPoints, imagePoints, imgSize, camMat_est, distCoeffs_est, rvecs, tvecs);
|
||||
cout << "Done" << endl;
|
||||
|
||||
cout << endl << "Average Reprojection error: " << rep_err/brds_num/cbg.cornersSize().area() << endl;
|
||||
cout << "==================================" << endl;
|
||||
cout << "Original camera matrix:\n" << camMat << endl;
|
||||
cout << "Original distCoeffs:\n" << distCoeffs << endl;
|
||||
cout << "==================================" << endl;
|
||||
cout << "Estimated camera matrix:\n" << (Mat_<double>&)camMat_est << endl;
|
||||
cout << "Estimated distCoeffs:\n" << (Mat_<double>&)distCoeffs_est << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Copy of tests/cv/src/chessboardgenerator code. Just do not want to add dependency.
|
||||
|
||||
|
||||
ChessBoardGenerator::ChessBoardGenerator(const Size& _patternSize) : sensorWidth(32), sensorHeight(24),
|
||||
squareEdgePointsNum(200), min_cos(std::sqrt(2.f)*0.5f), cov(0.5),
|
||||
patternSize(_patternSize), rendererResolutionMultiplier(4), tvec(Mat::zeros(1, 3, CV_32F))
|
||||
{
|
||||
Rodrigues(Mat::eye(3, 3, CV_32F), rvec);
|
||||
}
|
||||
|
||||
void cv::ChessBoardGenerator::generateEdge(const Point3f& p1, const Point3f& p2, vector<Point3f>& out) const
|
||||
{
|
||||
Point3f step = (p2 - p1) * (1.f/squareEdgePointsNum);
|
||||
for(size_t n = 0; n < squareEdgePointsNum; ++n)
|
||||
out.push_back( p1 + step * (float)n);
|
||||
}
|
||||
|
||||
Size cv::ChessBoardGenerator::cornersSize() const
|
||||
{
|
||||
return Size(patternSize.width-1, patternSize.height-1);
|
||||
}
|
||||
|
||||
struct Mult
|
||||
{
|
||||
float m;
|
||||
Mult(int mult) : m((float)mult) {}
|
||||
Point2f operator()(const Point2f& p)const { return p * m; }
|
||||
};
|
||||
|
||||
void cv::ChessBoardGenerator::generateBasis(Point3f& pb1, Point3f& pb2) const
|
||||
{
|
||||
RNG& rng = theRNG();
|
||||
|
||||
Vec3f n;
|
||||
for(;;)
|
||||
{
|
||||
n[0] = rng.uniform(-1.f, 1.f);
|
||||
n[1] = rng.uniform(-1.f, 1.f);
|
||||
n[2] = rng.uniform(-1.f, 1.f);
|
||||
float len = (float)norm(n);
|
||||
n[0]/=len;
|
||||
n[1]/=len;
|
||||
n[2]/=len;
|
||||
|
||||
if (fabs(n[2]) > min_cos)
|
||||
break;
|
||||
}
|
||||
|
||||
Vec3f n_temp = n; n_temp[0] += 100;
|
||||
Vec3f b1 = n.cross(n_temp);
|
||||
Vec3f b2 = n.cross(b1);
|
||||
float len_b1 = (float)norm(b1);
|
||||
float len_b2 = (float)norm(b2);
|
||||
|
||||
pb1 = Point3f(b1[0]/len_b1, b1[1]/len_b1, b1[2]/len_b1);
|
||||
pb2 = Point3f(b2[0]/len_b1, b2[1]/len_b2, b2[2]/len_b2);
|
||||
}
|
||||
|
||||
Mat cv::ChessBoardGenerator::generageChessBoard(const Mat& bg, const Mat& camMat, const Mat& distCoeffs,
|
||||
const Point3f& zero, const Point3f& pb1, const Point3f& pb2,
|
||||
float sqWidth, float sqHeight, const vector<Point3f>& whole,
|
||||
vector<Point2f>& corners) const
|
||||
{
|
||||
vector< vector<Point> > squares_black;
|
||||
for(int i = 0; i < patternSize.width; ++i)
|
||||
for(int j = 0; j < patternSize.height; ++j)
|
||||
if ( (i % 2 == 0 && j % 2 == 0) || (i % 2 != 0 && j % 2 != 0) )
|
||||
{
|
||||
vector<Point3f> pts_square3d;
|
||||
vector<Point2f> pts_square2d;
|
||||
|
||||
Point3f p1 = zero + (i + 0) * sqWidth * pb1 + (j + 0) * sqHeight * pb2;
|
||||
Point3f p2 = zero + (i + 1) * sqWidth * pb1 + (j + 0) * sqHeight * pb2;
|
||||
Point3f p3 = zero + (i + 1) * sqWidth * pb1 + (j + 1) * sqHeight * pb2;
|
||||
Point3f p4 = zero + (i + 0) * sqWidth * pb1 + (j + 1) * sqHeight * pb2;
|
||||
generateEdge(p1, p2, pts_square3d);
|
||||
generateEdge(p2, p3, pts_square3d);
|
||||
generateEdge(p3, p4, pts_square3d);
|
||||
generateEdge(p4, p1, pts_square3d);
|
||||
|
||||
projectPoints( Mat(pts_square3d), rvec, tvec, camMat, distCoeffs, pts_square2d);
|
||||
squares_black.resize(squares_black.size() + 1);
|
||||
vector<Point2f> temp;
|
||||
approxPolyDP(Mat(pts_square2d), temp, 1.0, true);
|
||||
transform(temp.begin(), temp.end(), back_inserter(squares_black.back()), Mult(rendererResolutionMultiplier));
|
||||
}
|
||||
|
||||
/* calculate corners */
|
||||
vector<Point3f> corners3d;
|
||||
for(int j = 0; j < patternSize.height - 1; ++j)
|
||||
for(int i = 0; i < patternSize.width - 1; ++i)
|
||||
corners3d.push_back(zero + (i + 1) * sqWidth * pb1 + (j + 1) * sqHeight * pb2);
|
||||
corners.clear();
|
||||
projectPoints( Mat(corners3d), rvec, tvec, camMat, distCoeffs, corners);
|
||||
|
||||
vector<Point3f> whole3d;
|
||||
vector<Point2f> whole2d;
|
||||
generateEdge(whole[0], whole[1], whole3d);
|
||||
generateEdge(whole[1], whole[2], whole3d);
|
||||
generateEdge(whole[2], whole[3], whole3d);
|
||||
generateEdge(whole[3], whole[0], whole3d);
|
||||
projectPoints( Mat(whole3d), rvec, tvec, camMat, distCoeffs, whole2d);
|
||||
vector<Point2f> temp_whole2d;
|
||||
approxPolyDP(Mat(whole2d), temp_whole2d, 1.0, true);
|
||||
|
||||
vector< vector<Point > > whole_contour(1);
|
||||
transform(temp_whole2d.begin(), temp_whole2d.end(),
|
||||
back_inserter(whole_contour.front()), Mult(rendererResolutionMultiplier));
|
||||
|
||||
Mat result;
|
||||
if (rendererResolutionMultiplier == 1)
|
||||
{
|
||||
result = bg.clone();
|
||||
drawContours(result, whole_contour, -1, Scalar::all(255), FILLED, LINE_AA);
|
||||
drawContours(result, squares_black, -1, Scalar::all(0), FILLED, LINE_AA);
|
||||
}
|
||||
else
|
||||
{
|
||||
Mat tmp;
|
||||
resize(bg, tmp, bg.size() * rendererResolutionMultiplier);
|
||||
drawContours(tmp, whole_contour, -1, Scalar::all(255), FILLED, LINE_AA);
|
||||
drawContours(tmp, squares_black, -1, Scalar::all(0), FILLED, LINE_AA);
|
||||
resize(tmp, result, bg.size(), 0, 0, INTER_AREA);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Mat cv::ChessBoardGenerator::operator ()(const Mat& bg, const Mat& camMat, const Mat& distCoeffs, vector<Point2f>& corners) const
|
||||
{
|
||||
cov = std::min(cov, 0.8);
|
||||
double fovx, fovy, focalLen;
|
||||
Point2d principalPoint;
|
||||
double aspect;
|
||||
calibrationMatrixValues( camMat, bg.size(), sensorWidth, sensorHeight,
|
||||
fovx, fovy, focalLen, principalPoint, aspect);
|
||||
|
||||
RNG& rng = theRNG();
|
||||
|
||||
float d1 = static_cast<float>(rng.uniform(0.1, 10.0));
|
||||
float ah = static_cast<float>(rng.uniform(-fovx/2 * cov, fovx/2 * cov) * CV_PI / 180);
|
||||
float av = static_cast<float>(rng.uniform(-fovy/2 * cov, fovy/2 * cov) * CV_PI / 180);
|
||||
|
||||
Point3f p;
|
||||
p.z = cos(ah) * d1;
|
||||
p.x = sin(ah) * d1;
|
||||
p.y = p.z * tan(av);
|
||||
|
||||
Point3f pb1, pb2;
|
||||
generateBasis(pb1, pb2);
|
||||
|
||||
float cbHalfWidth = static_cast<float>(norm(p) * sin( std::min(fovx, fovy) * 0.5 * CV_PI / 180));
|
||||
float cbHalfHeight = cbHalfWidth * patternSize.height / patternSize.width;
|
||||
|
||||
vector<Point3f> pts3d(4);
|
||||
vector<Point2f> pts2d(4);
|
||||
for(;;)
|
||||
{
|
||||
pts3d[0] = p + pb1 * cbHalfWidth + cbHalfHeight * pb2;
|
||||
pts3d[1] = p + pb1 * cbHalfWidth - cbHalfHeight * pb2;
|
||||
pts3d[2] = p - pb1 * cbHalfWidth - cbHalfHeight * pb2;
|
||||
pts3d[3] = p - pb1 * cbHalfWidth + cbHalfHeight * pb2;
|
||||
|
||||
/* can remake with better perf */
|
||||
projectPoints( Mat(pts3d), rvec, tvec, camMat, distCoeffs, pts2d);
|
||||
|
||||
bool inrect1 = pts2d[0].x < bg.cols && pts2d[0].y < bg.rows && pts2d[0].x > 0 && pts2d[0].y > 0;
|
||||
bool inrect2 = pts2d[1].x < bg.cols && pts2d[1].y < bg.rows && pts2d[1].x > 0 && pts2d[1].y > 0;
|
||||
bool inrect3 = pts2d[2].x < bg.cols && pts2d[2].y < bg.rows && pts2d[2].x > 0 && pts2d[2].y > 0;
|
||||
bool inrect4 = pts2d[3].x < bg.cols && pts2d[3].y < bg.rows && pts2d[3].x > 0 && pts2d[3].y > 0;
|
||||
|
||||
if ( inrect1 && inrect2 && inrect3 && inrect4)
|
||||
break;
|
||||
|
||||
cbHalfWidth*=0.8f;
|
||||
cbHalfHeight = cbHalfWidth * patternSize.height / patternSize.width;
|
||||
}
|
||||
|
||||
cbHalfWidth *= static_cast<float>(patternSize.width)/(patternSize.width + 1);
|
||||
cbHalfHeight *= static_cast<float>(patternSize.height)/(patternSize.height + 1);
|
||||
|
||||
Point3f zero = p - pb1 * cbHalfWidth - cbHalfHeight * pb2;
|
||||
float sqWidth = 2 * cbHalfWidth/patternSize.width;
|
||||
float sqHeight = 2 * cbHalfHeight/patternSize.height;
|
||||
|
||||
return generageChessBoard(bg, camMat, distCoeffs, zero, pb1, pb2, sqWidth, sqHeight, pts3d, corners);
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
#include <opencv2/core/utility.hpp>
|
||||
#include "opencv2/imgproc.hpp"
|
||||
#include "opencv2/highgui.hpp"
|
||||
#include "opencv2/contrib.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace cv;
|
||||
using namespace std;
|
||||
|
||||
static void help()
|
||||
{
|
||||
|
||||
cout << "\nThis program demonstrates Chamfer matching -- computing a distance between an \n"
|
||||
"edge template and a query edge image.\n"
|
||||
"Usage: \n"
|
||||
"./chamfer <image edge map> <template edge map>,"
|
||||
" By default the inputs are logo_in_clutter.png logo.png\n";
|
||||
}
|
||||
|
||||
const char* keys =
|
||||
{
|
||||
"{@logo1 |logo_in_clutter.png |image edge map }"
|
||||
"{@logo2 |logo.png |template edge map}"
|
||||
};
|
||||
|
||||
int main( int argc, const char** argv )
|
||||
{
|
||||
|
||||
help();
|
||||
CommandLineParser parser(argc, argv, keys);
|
||||
|
||||
string image = parser.get<string>(0);
|
||||
string templ = parser.get<string>(1);
|
||||
Mat img = imread(image.c_str(), 0);
|
||||
Mat tpl = imread(templ.c_str(), 0);
|
||||
|
||||
if (img.empty() || tpl.empty())
|
||||
{
|
||||
cout << "Could not read image file " << image << " or " << templ << "." << endl;
|
||||
return -1;
|
||||
}
|
||||
Mat cimg;
|
||||
cvtColor(img, cimg, COLOR_GRAY2BGR);
|
||||
|
||||
// if the image and the template are not edge maps but normal grayscale images,
|
||||
// you might want to uncomment the lines below to produce the maps. You can also
|
||||
// run Sobel instead of Canny.
|
||||
|
||||
// Canny(img, img, 5, 50, 3);
|
||||
// Canny(tpl, tpl, 5, 50, 3);
|
||||
|
||||
vector<vector<Point> > results;
|
||||
vector<float> costs;
|
||||
int best = chamerMatching( img, tpl, results, costs );
|
||||
if( best < 0 )
|
||||
{
|
||||
cout << "matching not found" << endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_t i, n = results[best].size();
|
||||
for( i = 0; i < n; i++ )
|
||||
{
|
||||
Point pt = results[best][i];
|
||||
if( pt.inside(Rect(0, 0, cimg.cols, cimg.rows)) )
|
||||
cimg.at<Vec3b>(pt) = Vec3b(0, 255, 0);
|
||||
}
|
||||
|
||||
imshow("result", cimg);
|
||||
|
||||
waitKey();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
#if defined(__linux__) || defined(LINUX) || defined(__APPLE__) || defined(ANDROID)
|
||||
|
||||
#include <opencv2/imgproc/imgproc.hpp> // Gaussian Blur
|
||||
#include <opencv2/core/core.hpp> // Basic OpenCV structures (cv::Mat, Scalar)
|
||||
#include <opencv2/highgui/highgui.hpp> // OpenCV window I/O
|
||||
#include <opencv2/features2d/features2d.hpp>
|
||||
#include <opencv2/contrib/detection_based_tracker.hpp>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
|
||||
const string WindowName = "Face Detection example";
|
||||
|
||||
class CascadeDetectorAdapter: public DetectionBasedTracker::IDetector
|
||||
{
|
||||
public:
|
||||
CascadeDetectorAdapter(cv::Ptr<cv::CascadeClassifier> detector):
|
||||
IDetector(),
|
||||
Detector(detector)
|
||||
{
|
||||
CV_Assert(detector);
|
||||
}
|
||||
|
||||
void detect(const cv::Mat &Image, std::vector<cv::Rect> &objects)
|
||||
{
|
||||
Detector->detectMultiScale(Image, objects, scaleFactor, minNeighbours, 0, minObjSize, maxObjSize);
|
||||
}
|
||||
|
||||
virtual ~CascadeDetectorAdapter()
|
||||
{}
|
||||
|
||||
private:
|
||||
CascadeDetectorAdapter();
|
||||
cv::Ptr<cv::CascadeClassifier> Detector;
|
||||
};
|
||||
|
||||
int main(int , char** )
|
||||
{
|
||||
namedWindow(WindowName);
|
||||
|
||||
VideoCapture VideoStream(0);
|
||||
|
||||
if (!VideoStream.isOpened())
|
||||
{
|
||||
printf("Error: Cannot open video stream from camera\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::string cascadeFrontalfilename = "../../data/lbpcascades/lbpcascade_frontalface.xml";
|
||||
cv::Ptr<cv::CascadeClassifier> cascade = makePtr<cv::CascadeClassifier>(cascadeFrontalfilename);
|
||||
cv::Ptr<DetectionBasedTracker::IDetector> MainDetector = makePtr<CascadeDetectorAdapter>(cascade);
|
||||
|
||||
cascade = makePtr<cv::CascadeClassifier>(cascadeFrontalfilename);
|
||||
cv::Ptr<DetectionBasedTracker::IDetector> TrackingDetector = makePtr<CascadeDetectorAdapter>(cascade);
|
||||
|
||||
DetectionBasedTracker::Parameters params;
|
||||
DetectionBasedTracker Detector(MainDetector, TrackingDetector, params);
|
||||
|
||||
if (!Detector.run())
|
||||
{
|
||||
printf("Error: Detector initialization failed\n");
|
||||
return 2;
|
||||
}
|
||||
|
||||
Mat ReferenceFrame;
|
||||
Mat GrayFrame;
|
||||
vector<Rect> Faces;
|
||||
|
||||
while(true)
|
||||
{
|
||||
VideoStream >> ReferenceFrame;
|
||||
cvtColor(ReferenceFrame, GrayFrame, COLOR_RGB2GRAY);
|
||||
Detector.process(GrayFrame);
|
||||
Detector.getObjects(Faces);
|
||||
|
||||
for (size_t i = 0; i < Faces.size(); i++)
|
||||
{
|
||||
rectangle(ReferenceFrame, Faces[i], Scalar(0,255,0));
|
||||
}
|
||||
|
||||
imshow(WindowName, ReferenceFrame);
|
||||
|
||||
if (waitKey(30) >= 0) break;
|
||||
}
|
||||
|
||||
Detector.stop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <stdio.h>
|
||||
int main()
|
||||
{
|
||||
printf("This sample works for UNIX or ANDROID only\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,193 +0,0 @@
|
||||
#if defined(__linux__) || defined(LINUX) || defined(__APPLE__) || defined(ANDROID)
|
||||
|
||||
#include <opencv2/core.hpp>
|
||||
#include <opencv2/core/utility.hpp>
|
||||
#include <opencv2/imgproc.hpp>
|
||||
#include <opencv2/highgui.hpp>
|
||||
#include <opencv2/objdetect.hpp>
|
||||
#include "opencv2/contrib/detection_based_tracker.hpp"
|
||||
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <stdio.h>
|
||||
|
||||
#define DEBUGLOGS 1
|
||||
|
||||
|
||||
#ifdef ANDROID
|
||||
#include <android/log.h>
|
||||
#define LOG_TAG "DETECTIONBASEDTRACKER__TEST_APPLICAT"
|
||||
#define LOGD0(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__))
|
||||
#define LOGI0(...) ((void)__android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__))
|
||||
#define LOGW0(...) ((void)__android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__))
|
||||
#define LOGE0(...) ((void)__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__))
|
||||
#else
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define LOGD0(_str, ...) do{printf(_str , ## __VA_ARGS__); printf("\n");fflush(stdout);} while(0)
|
||||
#define LOGI0(_str, ...) do{printf(_str , ## __VA_ARGS__); printf("\n");fflush(stdout);} while(0)
|
||||
#define LOGW0(_str, ...) do{printf(_str , ## __VA_ARGS__); printf("\n");fflush(stdout);} while(0)
|
||||
#define LOGE0(_str, ...) do{printf(_str , ## __VA_ARGS__); printf("\n");fflush(stdout);} while(0)
|
||||
#endif
|
||||
|
||||
#if DEBUGLOGS
|
||||
#define LOGD(_str, ...) LOGD0(_str , ## __VA_ARGS__)
|
||||
#define LOGI(_str, ...) LOGI0(_str , ## __VA_ARGS__)
|
||||
#define LOGW(_str, ...) LOGW0(_str , ## __VA_ARGS__)
|
||||
#define LOGE(_str, ...) LOGE0(_str , ## __VA_ARGS__)
|
||||
#else
|
||||
#define LOGD(...) do{} while(0)
|
||||
#define LOGI(...) do{} while(0)
|
||||
#define LOGW(...) do{} while(0)
|
||||
#define LOGE(...) do{} while(0)
|
||||
#endif
|
||||
|
||||
using namespace cv;
|
||||
using namespace std;
|
||||
|
||||
#define ORIGINAL 0
|
||||
#define SHOULD_USE_EXTERNAL_BUFFERS 1
|
||||
|
||||
static void usage()
|
||||
{
|
||||
LOGE0("usage: filepattern outfilepattern cascadefile");
|
||||
LOGE0("\t where ");
|
||||
LOGE0("\t filepattern --- pattern for the paths to the source images");
|
||||
LOGE0("\t (e.g.\"./Videos/FACESJPG2/Faces2_%%08d.jpg\" ");
|
||||
LOGE0("\t outfilepattern --- pattern for the paths for images which will be generated");
|
||||
LOGE0("\t (e.g.\"./resFaces2_%%08d.jpg\" ");
|
||||
LOGE0("\t cascadefile --- path to the cascade file");
|
||||
LOGE0("\t (e.g.\"opencv/data/lbpcascades/lbpcascade_frontalface.xml\" ");
|
||||
}
|
||||
|
||||
class CascadeDetectorAdapter: public DetectionBasedTracker::IDetector
|
||||
{
|
||||
public:
|
||||
CascadeDetectorAdapter(cv::Ptr<cv::CascadeClassifier> detector):
|
||||
Detector(detector)
|
||||
{
|
||||
CV_Assert(detector);
|
||||
}
|
||||
|
||||
void detect(const cv::Mat &Image, std::vector<cv::Rect> &objects)
|
||||
{
|
||||
Detector->detectMultiScale(Image, objects, 1.1, 3, 0, minObjSize, maxObjSize);
|
||||
}
|
||||
virtual ~CascadeDetectorAdapter()
|
||||
{}
|
||||
|
||||
private:
|
||||
CascadeDetectorAdapter();
|
||||
cv::Ptr<cv::CascadeClassifier> Detector;
|
||||
};
|
||||
|
||||
static int test_FaceDetector(int argc, char *argv[])
|
||||
{
|
||||
if (argc < 4)
|
||||
{
|
||||
usage();
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char* filepattern=argv[1];
|
||||
const char* outfilepattern=argv[2];
|
||||
const char* cascadefile=argv[3];
|
||||
LOGD0("filepattern='%s'", filepattern);
|
||||
LOGD0("outfilepattern='%s'", outfilepattern);
|
||||
LOGD0("cascadefile='%s'", cascadefile);
|
||||
|
||||
vector<Mat> images;
|
||||
{
|
||||
char filename[256];
|
||||
for(int n=1; ; n++)
|
||||
{
|
||||
snprintf(filename, sizeof(filename), filepattern, n);
|
||||
LOGD("filename='%s'", filename);
|
||||
Mat m0;
|
||||
m0=imread(filename);
|
||||
if (m0.empty())
|
||||
{
|
||||
LOGI0("Cannot read the file --- break");
|
||||
break;
|
||||
}
|
||||
images.push_back(m0);
|
||||
}
|
||||
LOGD("read %d images", (int)images.size());
|
||||
}
|
||||
|
||||
std::string cascadeFrontalfilename=cascadefile;
|
||||
cv::Ptr<cv::CascadeClassifier> cascade = makePtr<cv::CascadeClassifier>(cascadeFrontalfilename);
|
||||
cv::Ptr<DetectionBasedTracker::IDetector> MainDetector = makePtr<CascadeDetectorAdapter>(cascade);
|
||||
|
||||
cascade = makePtr<cv::CascadeClassifier>(cascadeFrontalfilename);
|
||||
cv::Ptr<DetectionBasedTracker::IDetector> TrackingDetector = makePtr<CascadeDetectorAdapter>(cascade);
|
||||
|
||||
DetectionBasedTracker::Parameters params;
|
||||
DetectionBasedTracker fd(MainDetector, TrackingDetector, params);
|
||||
|
||||
fd.run();
|
||||
|
||||
Mat gray;
|
||||
Mat m;
|
||||
|
||||
int64 tprev=getTickCount();
|
||||
double freq=getTickFrequency();
|
||||
|
||||
int num_images=images.size();
|
||||
for(int n=1; n <= num_images; n++)
|
||||
{
|
||||
int64 tcur=getTickCount();
|
||||
int64 dt=tcur-tprev;
|
||||
tprev=tcur;
|
||||
double t_ms=((double)dt)/freq * 1000.0;
|
||||
LOGD("\n\nSTEP n=%d from prev step %f ms\n", n, t_ms);
|
||||
m=images[n-1];
|
||||
CV_Assert(! m.empty());
|
||||
cvtColor(m, gray, COLOR_BGR2GRAY);
|
||||
|
||||
fd.process(gray);
|
||||
|
||||
vector<Rect> result;
|
||||
fd.getObjects(result);
|
||||
|
||||
for(size_t i=0; i < result.size(); i++)
|
||||
{
|
||||
Rect r=result[i];
|
||||
CV_Assert(r.area() > 0);
|
||||
Point tl=r.tl();
|
||||
Point br=r.br();
|
||||
Scalar color=Scalar(0, 250, 0);
|
||||
rectangle(m, tl, br, color, 3);
|
||||
}
|
||||
}
|
||||
|
||||
char outfilename[256];
|
||||
for(int n=1; n <= num_images; n++)
|
||||
{
|
||||
snprintf(outfilename, sizeof(outfilename), outfilepattern, n);
|
||||
LOGD("outfilename='%s'", outfilename);
|
||||
m=images[n-1];
|
||||
imwrite(outfilename, m);
|
||||
}
|
||||
|
||||
fd.stop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
return test_FaceDetector(argc, argv);
|
||||
}
|
||||
|
||||
#else // #if defined(__linux__) || defined(LINUX) || defined(__APPLE__) || defined(ANDROID)
|
||||
|
||||
#include <stdio.h>
|
||||
int main()
|
||||
{
|
||||
printf("This sample works for UNIX or ANDROID only\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,983 +0,0 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// Intel License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of Intel Corporation may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "opencv2/imgproc.hpp"
|
||||
#include "opencv2/highgui.hpp"
|
||||
#include "opencv2/features2d.hpp"
|
||||
#include "opencv2/legacy.hpp"
|
||||
|
||||
#include <limits>
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
|
||||
|
||||
string data_path;
|
||||
/****************************************************************************************\
|
||||
* Functions to evaluate affine covariant detectors and descriptors. *
|
||||
\****************************************************************************************/
|
||||
|
||||
static inline Point2f applyHomography( const Mat_<double>& H, const Point2f& pt )
|
||||
{
|
||||
double z = H(2,0)*pt.x + H(2,1)*pt.y + H(2,2);
|
||||
if( z )
|
||||
{
|
||||
double w = 1./z;
|
||||
return Point2f( (float)((H(0,0)*pt.x + H(0,1)*pt.y + H(0,2))*w),
|
||||
(float)((H(1,0)*pt.x + H(1,1)*pt.y + H(1,2))*w) );
|
||||
}
|
||||
return Point2f( numeric_limits<float>::max(), numeric_limits<float>::max() );
|
||||
}
|
||||
|
||||
static inline void linearizeHomographyAt( const Mat_<double>& H, const Point2f& pt, Mat_<double>& A )
|
||||
{
|
||||
A.create(2,2);
|
||||
double p1 = H(0,0)*pt.x + H(0,1)*pt.y + H(0,2),
|
||||
p2 = H(1,0)*pt.x + H(1,1)*pt.y + H(1,2),
|
||||
p3 = H(2,0)*pt.x + H(2,1)*pt.y + H(2,2),
|
||||
p3_2 = p3*p3;
|
||||
if( p3 )
|
||||
{
|
||||
A(0,0) = H(0,0)/p3 - p1*H(2,0)/p3_2; // fxdx
|
||||
A(0,1) = H(0,1)/p3 - p1*H(2,1)/p3_2; // fxdy
|
||||
|
||||
A(1,0) = H(1,0)/p3 - p2*H(2,0)/p3_2; // fydx
|
||||
A(1,1) = H(1,1)/p3 - p2*H(2,1)/p3_2; // fydx
|
||||
}
|
||||
else
|
||||
A.setTo(Scalar::all(numeric_limits<double>::max()));
|
||||
}
|
||||
|
||||
static void calcKeyPointProjections( const vector<KeyPoint>& src, const Mat_<double>& H, vector<KeyPoint>& dst )
|
||||
{
|
||||
if( !src.empty() )
|
||||
{
|
||||
CV_Assert( !H.empty() && H.cols == 3 && H.rows == 3);
|
||||
dst.resize(src.size());
|
||||
vector<KeyPoint>::const_iterator srcIt = src.begin();
|
||||
vector<KeyPoint>::iterator dstIt = dst.begin();
|
||||
for( ; srcIt != src.end(); ++srcIt, ++dstIt )
|
||||
{
|
||||
Point2f dstPt = applyHomography(H, srcIt->pt);
|
||||
|
||||
float srcSize2 = srcIt->size * srcIt->size;
|
||||
Mat_<double> M(2, 2);
|
||||
M(0,0) = M(1,1) = 1./srcSize2;
|
||||
M(1,0) = M(0,1) = 0;
|
||||
Mat_<double> invM; invert(M, invM);
|
||||
Mat_<double> Aff; linearizeHomographyAt(H, srcIt->pt, Aff);
|
||||
Mat_<double> dstM; invert(Aff*invM*Aff.t(), dstM);
|
||||
Mat_<double> eval; eigen( dstM, eval );
|
||||
CV_Assert( eval(0,0) && eval(1,0) );
|
||||
float dstSize = (float)pow(1./(eval(0,0)*eval(1,0)), 0.25);
|
||||
|
||||
// TODO: check angle projection
|
||||
float srcAngleRad = (float)(srcIt->angle*CV_PI/180);
|
||||
Point2f vec1(cos(srcAngleRad), sin(srcAngleRad)), vec2;
|
||||
vec2.x = (float)(Aff(0,0)*vec1.x + Aff(0,1)*vec1.y);
|
||||
vec2.y = (float)(Aff(1,0)*vec1.x + Aff(0,1)*vec1.y);
|
||||
float dstAngleGrad = fastAtan2(vec2.y, vec2.x);
|
||||
|
||||
*dstIt = KeyPoint( dstPt, dstSize, dstAngleGrad, srcIt->response, srcIt->octave, srcIt->class_id );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void filterKeyPointsByImageSize( vector<KeyPoint>& keypoints, const Size& imgSize )
|
||||
{
|
||||
if( !keypoints.empty() )
|
||||
{
|
||||
vector<KeyPoint> filtered;
|
||||
filtered.reserve(keypoints.size());
|
||||
Rect r(0, 0, imgSize.width, imgSize.height);
|
||||
vector<KeyPoint>::const_iterator it = keypoints.begin();
|
||||
for( int i = 0; it != keypoints.end(); ++it, i++ )
|
||||
if( r.contains(it->pt) )
|
||||
filtered.push_back(*it);
|
||||
keypoints.assign(filtered.begin(), filtered.end());
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************************\
|
||||
* Detectors evaluation *
|
||||
\****************************************************************************************/
|
||||
const int DATASETS_COUNT = 8;
|
||||
const int TEST_CASE_COUNT = 5;
|
||||
|
||||
const string IMAGE_DATASETS_DIR = "detectors_descriptors_evaluation/images_datasets/";
|
||||
const string DETECTORS_DIR = "detectors_descriptors_evaluation/detectors/";
|
||||
const string DESCRIPTORS_DIR = "detectors_descriptors_evaluation/descriptors/";
|
||||
const string KEYPOINTS_DIR = "detectors_descriptors_evaluation/keypoints_datasets/";
|
||||
|
||||
const string PARAMS_POSTFIX = "_params.xml";
|
||||
const string RES_POSTFIX = "_res.xml";
|
||||
|
||||
const string REPEAT = "repeatability";
|
||||
const string CORRESP_COUNT = "correspondence_count";
|
||||
|
||||
string DATASET_NAMES[DATASETS_COUNT] = { "bark", "bikes", "boat", "graf", "leuven", "trees", "ubc", "wall"};
|
||||
|
||||
string DEFAULT_PARAMS = "default";
|
||||
|
||||
string IS_ACTIVE_PARAMS = "isActiveParams";
|
||||
string IS_SAVE_KEYPOINTS = "isSaveKeypoints";
|
||||
|
||||
|
||||
class BaseQualityEvaluator
|
||||
{
|
||||
public:
|
||||
BaseQualityEvaluator( const char* _algName, const char* _testName ) : algName(_algName), testName(_testName)
|
||||
{
|
||||
//TODO: change this
|
||||
isWriteGraphicsData = true;
|
||||
}
|
||||
|
||||
void run();
|
||||
|
||||
virtual ~BaseQualityEvaluator(){}
|
||||
|
||||
protected:
|
||||
virtual string getRunParamsFilename() const = 0;
|
||||
virtual string getResultsFilename() const = 0;
|
||||
virtual string getPlotPath() const = 0;
|
||||
|
||||
virtual void calcQualityClear( int datasetIdx ) = 0;
|
||||
virtual bool isCalcQualityEmpty( int datasetIdx ) const = 0;
|
||||
|
||||
void readAllDatasetsRunParams();
|
||||
virtual void readDatasetRunParams( FileNode& fn, int datasetIdx ) = 0;
|
||||
void writeAllDatasetsRunParams() const;
|
||||
virtual void writeDatasetRunParams( FileStorage& fs, int datasetIdx ) const = 0;
|
||||
void setDefaultAllDatasetsRunParams();
|
||||
virtual void setDefaultDatasetRunParams( int datasetIdx ) = 0;
|
||||
virtual void readDefaultRunParams( FileNode& /*fn*/ ) {}
|
||||
virtual void writeDefaultRunParams( FileStorage& /*fs*/ ) const {}
|
||||
|
||||
bool readDataset( const string& datasetName, vector<Mat>& Hs, vector<Mat>& imgs );
|
||||
|
||||
virtual void readAlgorithm() {}
|
||||
virtual void processRunParamsFile() {}
|
||||
virtual void runDatasetTest( const vector<Mat>& /*imgs*/, const vector<Mat>& /*Hs*/, int /*di*/, int& /*progress*/ ) {}
|
||||
|
||||
virtual void processResults( int datasetIdx );
|
||||
virtual void processResults();
|
||||
virtual void writePlotData( int /*datasetIdx*/ ) const {}
|
||||
|
||||
string algName, testName;
|
||||
bool isWriteParams, isWriteGraphicsData;
|
||||
};
|
||||
|
||||
void BaseQualityEvaluator::readAllDatasetsRunParams()
|
||||
{
|
||||
string filename = getRunParamsFilename();
|
||||
FileStorage fs( filename, FileStorage::READ );
|
||||
if( !fs.isOpened() )
|
||||
{
|
||||
isWriteParams = true;
|
||||
setDefaultAllDatasetsRunParams();
|
||||
printf("All runParams are default.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
isWriteParams = false;
|
||||
FileNode topfn = fs.getFirstTopLevelNode();
|
||||
|
||||
FileNode pfn = topfn[DEFAULT_PARAMS];
|
||||
readDefaultRunParams(pfn);
|
||||
|
||||
for( int i = 0; i < DATASETS_COUNT; i++ )
|
||||
{
|
||||
FileNode fn = topfn[DATASET_NAMES[i]];
|
||||
if( fn.empty() )
|
||||
{
|
||||
printf( "%d-runParams is default.\n", i);
|
||||
setDefaultDatasetRunParams(i);
|
||||
}
|
||||
else
|
||||
readDatasetRunParams(fn, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BaseQualityEvaluator::writeAllDatasetsRunParams() const
|
||||
{
|
||||
string filename = getRunParamsFilename();
|
||||
FileStorage fs( filename, FileStorage::WRITE );
|
||||
if( fs.isOpened() )
|
||||
{
|
||||
fs << "run_params" << "{"; // top file node
|
||||
fs << DEFAULT_PARAMS << "{";
|
||||
writeDefaultRunParams(fs);
|
||||
fs << "}";
|
||||
for( int i = 0; i < DATASETS_COUNT; i++ )
|
||||
{
|
||||
fs << DATASET_NAMES[i] << "{";
|
||||
writeDatasetRunParams(fs, i);
|
||||
fs << "}";
|
||||
}
|
||||
fs << "}";
|
||||
}
|
||||
else
|
||||
printf( "File %s for writing run params can not be opened.\n", filename.c_str() );
|
||||
}
|
||||
|
||||
void BaseQualityEvaluator::setDefaultAllDatasetsRunParams()
|
||||
{
|
||||
for( int i = 0; i < DATASETS_COUNT; i++ )
|
||||
setDefaultDatasetRunParams(i);
|
||||
}
|
||||
|
||||
bool BaseQualityEvaluator::readDataset( const string& datasetName, vector<Mat>& Hs, vector<Mat>& imgs )
|
||||
{
|
||||
Hs.resize( TEST_CASE_COUNT );
|
||||
imgs.resize( TEST_CASE_COUNT+1 );
|
||||
string dirname = data_path + IMAGE_DATASETS_DIR + datasetName + "/";
|
||||
for( int i = 0; i < (int)Hs.size(); i++ )
|
||||
{
|
||||
stringstream filename; filename << "H1to" << i+2 << "p.xml";
|
||||
FileStorage fs( dirname + filename.str(), FileStorage::READ );
|
||||
if( !fs.isOpened() )
|
||||
{
|
||||
cout << "filename " << dirname + filename.str() << endl;
|
||||
FileStorage fs2( dirname + filename.str(), FileStorage::READ );
|
||||
return false;
|
||||
}
|
||||
fs.getFirstTopLevelNode() >> Hs[i];
|
||||
}
|
||||
|
||||
for( int i = 0; i < (int)imgs.size(); i++ )
|
||||
{
|
||||
stringstream filename; filename << "img" << i+1 << ".png";
|
||||
imgs[i] = imread( dirname + filename.str(), 0 );
|
||||
if( imgs[i].empty() )
|
||||
{
|
||||
cout << "filename " << filename.str() << endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void BaseQualityEvaluator::processResults( int datasetIdx )
|
||||
{
|
||||
if( isWriteGraphicsData )
|
||||
writePlotData( datasetIdx );
|
||||
}
|
||||
|
||||
void BaseQualityEvaluator::processResults()
|
||||
{
|
||||
if( isWriteParams )
|
||||
writeAllDatasetsRunParams();
|
||||
}
|
||||
|
||||
void BaseQualityEvaluator::run()
|
||||
{
|
||||
readAlgorithm ();
|
||||
processRunParamsFile ();
|
||||
|
||||
int notReadDatasets = 0;
|
||||
int progress = 0;
|
||||
|
||||
FileStorage runParamsFS( getRunParamsFilename(), FileStorage::READ );
|
||||
isWriteParams = (! runParamsFS.isOpened());
|
||||
FileNode topfn = runParamsFS.getFirstTopLevelNode();
|
||||
FileNode defaultParams = topfn[DEFAULT_PARAMS];
|
||||
readDefaultRunParams (defaultParams);
|
||||
|
||||
cout << testName << endl;
|
||||
for(int di = 0; di < DATASETS_COUNT; di++ )
|
||||
{
|
||||
cout << "Dataset " << di << " [" << DATASET_NAMES[di] << "] " << flush;
|
||||
vector<Mat> imgs, Hs;
|
||||
if( !readDataset( DATASET_NAMES[di], Hs, imgs ) )
|
||||
{
|
||||
calcQualityClear (di);
|
||||
printf( "Images or homography matrices of dataset named %s can not be read\n",
|
||||
DATASET_NAMES[di].c_str());
|
||||
notReadDatasets++;
|
||||
continue;
|
||||
}
|
||||
|
||||
FileNode fn = topfn[DATASET_NAMES[di]];
|
||||
readDatasetRunParams(fn, di);
|
||||
|
||||
runDatasetTest (imgs, Hs, di, progress);
|
||||
processResults( di );
|
||||
cout << endl;
|
||||
}
|
||||
if( notReadDatasets == DATASETS_COUNT )
|
||||
{
|
||||
printf( "All datasets were not be read\n");
|
||||
exit(-1);
|
||||
}
|
||||
else
|
||||
processResults();
|
||||
runParamsFS.release();
|
||||
}
|
||||
|
||||
|
||||
|
||||
class DetectorQualityEvaluator : public BaseQualityEvaluator
|
||||
{
|
||||
public:
|
||||
DetectorQualityEvaluator( const char* _detectorName, const char* _testName ) : BaseQualityEvaluator( _detectorName, _testName )
|
||||
{
|
||||
calcQuality.resize(DATASETS_COUNT);
|
||||
isSaveKeypoints.resize(DATASETS_COUNT);
|
||||
isActiveParams.resize(DATASETS_COUNT);
|
||||
|
||||
isSaveKeypointsDefault = false;
|
||||
isActiveParamsDefault = false;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual string getRunParamsFilename() const;
|
||||
virtual string getResultsFilename() const;
|
||||
virtual string getPlotPath() const;
|
||||
|
||||
virtual void calcQualityClear( int datasetIdx );
|
||||
virtual bool isCalcQualityEmpty( int datasetIdx ) const;
|
||||
|
||||
virtual void readDatasetRunParams( FileNode& fn, int datasetIdx );
|
||||
virtual void writeDatasetRunParams( FileStorage& fs, int datasetIdx ) const;
|
||||
virtual void setDefaultDatasetRunParams( int datasetIdx );
|
||||
virtual void readDefaultRunParams( FileNode &fn );
|
||||
virtual void writeDefaultRunParams( FileStorage &fs ) const;
|
||||
|
||||
virtual void writePlotData( int di ) const;
|
||||
|
||||
void openToWriteKeypointsFile( FileStorage& fs, int datasetIdx );
|
||||
|
||||
virtual void readAlgorithm();
|
||||
virtual void processRunParamsFile() {}
|
||||
virtual void runDatasetTest( const vector<Mat> &imgs, const vector<Mat> &Hs, int di, int &progress );
|
||||
|
||||
Ptr<FeatureDetector> specificDetector;
|
||||
Ptr<FeatureDetector> defaultDetector;
|
||||
|
||||
struct Quality
|
||||
{
|
||||
float repeatability;
|
||||
int correspondenceCount;
|
||||
};
|
||||
vector<vector<Quality> > calcQuality;
|
||||
|
||||
vector<bool> isSaveKeypoints;
|
||||
vector<bool> isActiveParams;
|
||||
|
||||
bool isSaveKeypointsDefault;
|
||||
bool isActiveParamsDefault;
|
||||
};
|
||||
|
||||
string DetectorQualityEvaluator::getRunParamsFilename() const
|
||||
{
|
||||
return data_path + DETECTORS_DIR + algName + PARAMS_POSTFIX;
|
||||
}
|
||||
|
||||
string DetectorQualityEvaluator::getResultsFilename() const
|
||||
{
|
||||
return data_path + DETECTORS_DIR + algName + RES_POSTFIX;
|
||||
}
|
||||
|
||||
string DetectorQualityEvaluator::getPlotPath() const
|
||||
{
|
||||
return data_path + DETECTORS_DIR + "plots/";
|
||||
}
|
||||
|
||||
void DetectorQualityEvaluator::calcQualityClear( int datasetIdx )
|
||||
{
|
||||
calcQuality[datasetIdx].clear();
|
||||
}
|
||||
|
||||
bool DetectorQualityEvaluator::isCalcQualityEmpty( int datasetIdx ) const
|
||||
{
|
||||
return calcQuality[datasetIdx].empty();
|
||||
}
|
||||
|
||||
void DetectorQualityEvaluator::readDefaultRunParams (FileNode &fn)
|
||||
{
|
||||
if (! fn.empty() )
|
||||
{
|
||||
isSaveKeypointsDefault = (int)fn[IS_SAVE_KEYPOINTS] != 0;
|
||||
defaultDetector->read (fn);
|
||||
}
|
||||
}
|
||||
|
||||
void DetectorQualityEvaluator::writeDefaultRunParams (FileStorage &fs) const
|
||||
{
|
||||
fs << IS_SAVE_KEYPOINTS << isSaveKeypointsDefault;
|
||||
defaultDetector->write (fs);
|
||||
}
|
||||
|
||||
void DetectorQualityEvaluator::readDatasetRunParams( FileNode& fn, int datasetIdx )
|
||||
{
|
||||
isActiveParams[datasetIdx] = (int)fn[IS_ACTIVE_PARAMS] != 0;
|
||||
if (isActiveParams[datasetIdx])
|
||||
{
|
||||
isSaveKeypoints[datasetIdx] = (int)fn[IS_SAVE_KEYPOINTS] != 0;
|
||||
specificDetector->read (fn);
|
||||
}
|
||||
else
|
||||
{
|
||||
setDefaultDatasetRunParams(datasetIdx);
|
||||
}
|
||||
}
|
||||
|
||||
void DetectorQualityEvaluator::writeDatasetRunParams( FileStorage& fs, int datasetIdx ) const
|
||||
{
|
||||
fs << IS_ACTIVE_PARAMS << isActiveParams[datasetIdx];
|
||||
fs << IS_SAVE_KEYPOINTS << isSaveKeypoints[datasetIdx];
|
||||
defaultDetector->write (fs);
|
||||
}
|
||||
|
||||
void DetectorQualityEvaluator::setDefaultDatasetRunParams( int datasetIdx )
|
||||
{
|
||||
isSaveKeypoints[datasetIdx] = isSaveKeypointsDefault;
|
||||
isActiveParams[datasetIdx] = isActiveParamsDefault;
|
||||
}
|
||||
|
||||
void DetectorQualityEvaluator::writePlotData(int di ) const
|
||||
{
|
||||
int imgXVals[] = { 2, 3, 4, 5, 6 }; // if scale, blur or light changes
|
||||
int viewpointXVals[] = { 20, 30, 40, 50, 60 }; // if viewpoint changes
|
||||
int jpegXVals[] = { 60, 80, 90, 95, 98 }; // if jpeg compression
|
||||
|
||||
int* xVals = 0;
|
||||
if( !DATASET_NAMES[di].compare("ubc") )
|
||||
{
|
||||
xVals = jpegXVals;
|
||||
}
|
||||
else if( !DATASET_NAMES[di].compare("graf") || !DATASET_NAMES[di].compare("wall") )
|
||||
{
|
||||
xVals = viewpointXVals;
|
||||
}
|
||||
else
|
||||
xVals = imgXVals;
|
||||
|
||||
stringstream rFilename, cFilename;
|
||||
rFilename << getPlotPath() << algName << "_" << DATASET_NAMES[di] << "_repeatability.csv";
|
||||
cFilename << getPlotPath() << algName << "_" << DATASET_NAMES[di] << "_correspondenceCount.csv";
|
||||
ofstream rfile(rFilename.str().c_str()), cfile(cFilename.str().c_str());
|
||||
for( int ci = 0; ci < TEST_CASE_COUNT; ci++ )
|
||||
{
|
||||
rfile << xVals[ci] << ", " << calcQuality[di][ci].repeatability << endl;
|
||||
cfile << xVals[ci] << ", " << calcQuality[di][ci].correspondenceCount << endl;
|
||||
}
|
||||
}
|
||||
|
||||
void DetectorQualityEvaluator::openToWriteKeypointsFile( FileStorage& fs, int datasetIdx )
|
||||
{
|
||||
string filename = data_path + KEYPOINTS_DIR + algName + "_"+ DATASET_NAMES[datasetIdx] + ".xml.gz" ;
|
||||
|
||||
fs.open(filename, FileStorage::WRITE);
|
||||
if( !fs.isOpened() )
|
||||
printf( "keypoints can not be written in file %s because this file can not be opened\n", filename.c_str() );
|
||||
}
|
||||
|
||||
inline void writeKeypoints( FileStorage& fs, const vector<KeyPoint>& keypoints, int imgIdx )
|
||||
{
|
||||
if( fs.isOpened() )
|
||||
{
|
||||
stringstream imgName; imgName << "img" << imgIdx;
|
||||
write( fs, imgName.str(), keypoints );
|
||||
}
|
||||
}
|
||||
|
||||
inline void readKeypoints( FileStorage& fs, vector<KeyPoint>& keypoints, int imgIdx )
|
||||
{
|
||||
CV_Assert( fs.isOpened() );
|
||||
stringstream imgName; imgName << "img" << imgIdx;
|
||||
read( fs[imgName.str()], keypoints);
|
||||
}
|
||||
|
||||
void DetectorQualityEvaluator::readAlgorithm ()
|
||||
{
|
||||
defaultDetector = FeatureDetector::create( algName );
|
||||
specificDetector = FeatureDetector::create( algName );
|
||||
if( !defaultDetector )
|
||||
{
|
||||
printf( "Algorithm can not be read\n" );
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
static int update_progress( const string& /*name*/, int progress, int test_case_idx, int count, double dt )
|
||||
{
|
||||
int width = 60 /*- (int)name.length()*/;
|
||||
if( count > 0 )
|
||||
{
|
||||
int t = cvRound( ((double)test_case_idx * width)/count );
|
||||
if( t > progress )
|
||||
{
|
||||
cout << "." << flush;
|
||||
progress = t;
|
||||
}
|
||||
}
|
||||
else if( cvRound(dt) > progress )
|
||||
{
|
||||
cout << "." << flush;
|
||||
progress = cvRound(dt);
|
||||
}
|
||||
|
||||
return progress;
|
||||
}
|
||||
|
||||
void DetectorQualityEvaluator::runDatasetTest (const vector<Mat> &imgs, const vector<Mat> &Hs, int di, int &progress)
|
||||
{
|
||||
Ptr<FeatureDetector> detector = isActiveParams[di] ? specificDetector : defaultDetector;
|
||||
FileStorage keypontsFS;
|
||||
if( isSaveKeypoints[di] )
|
||||
openToWriteKeypointsFile( keypontsFS, di );
|
||||
|
||||
calcQuality[di].resize(TEST_CASE_COUNT);
|
||||
|
||||
vector<KeyPoint> keypoints1;
|
||||
detector->detect( imgs[0], keypoints1 );
|
||||
writeKeypoints( keypontsFS, keypoints1, 0);
|
||||
int progressCount = DATASETS_COUNT*TEST_CASE_COUNT;
|
||||
|
||||
for( int ci = 0; ci < TEST_CASE_COUNT; ci++ )
|
||||
{
|
||||
progress = update_progress( testName, progress, di*TEST_CASE_COUNT + ci + 1, progressCount, 0 );
|
||||
vector<KeyPoint> keypoints2;
|
||||
float rep;
|
||||
evaluateFeatureDetector( imgs[0], imgs[ci+1], Hs[ci], &keypoints1, &keypoints2,
|
||||
rep, calcQuality[di][ci].correspondenceCount,
|
||||
detector );
|
||||
calcQuality[di][ci].repeatability = rep == -1 ? rep : 100.f*rep;
|
||||
writeKeypoints( keypontsFS, keypoints2, ci+1);
|
||||
}
|
||||
}
|
||||
|
||||
// static void testLog( bool isBadAccuracy )
|
||||
// {
|
||||
// if( isBadAccuracy )
|
||||
// printf(" bad accuracy\n");
|
||||
// else
|
||||
// printf("\n");
|
||||
// }
|
||||
|
||||
/****************************************************************************************\
|
||||
* Descriptors evaluation *
|
||||
\****************************************************************************************/
|
||||
|
||||
const string RECALL = "recall";
|
||||
const string PRECISION = "precision";
|
||||
|
||||
const string KEYPOINTS_FILENAME = "keypointsFilename";
|
||||
const string PROJECT_KEYPOINTS_FROM_1IMAGE = "projectKeypointsFrom1Image";
|
||||
const string MATCH_FILTER = "matchFilter";
|
||||
const string RUN_PARAMS_IS_IDENTICAL = "runParamsIsIdentical";
|
||||
|
||||
const string ONE_WAY_TRAIN_DIR = "detectors_descriptors_evaluation/one_way_train_images/";
|
||||
const string ONE_WAY_IMAGES_LIST = "one_way_train_images.txt";
|
||||
|
||||
class DescriptorQualityEvaluator : public BaseQualityEvaluator
|
||||
{
|
||||
public:
|
||||
enum{ NO_MATCH_FILTER = 0 };
|
||||
DescriptorQualityEvaluator( const char* _descriptorName, const char* _testName, const char* _matcherName = 0 ) :
|
||||
BaseQualityEvaluator( _descriptorName, _testName )
|
||||
{
|
||||
calcQuality.resize(DATASETS_COUNT);
|
||||
calcDatasetQuality.resize(DATASETS_COUNT);
|
||||
commRunParams.resize(DATASETS_COUNT);
|
||||
|
||||
commRunParamsDefault.projectKeypointsFrom1Image = true;
|
||||
commRunParamsDefault.matchFilter = NO_MATCH_FILTER;
|
||||
commRunParamsDefault.isActiveParams = false;
|
||||
|
||||
if( _matcherName )
|
||||
matcherName = _matcherName;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual string getRunParamsFilename() const;
|
||||
virtual string getResultsFilename() const;
|
||||
virtual string getPlotPath() const;
|
||||
|
||||
virtual void calcQualityClear( int datasetIdx );
|
||||
virtual bool isCalcQualityEmpty( int datasetIdx ) const;
|
||||
|
||||
virtual void readDatasetRunParams( FileNode& fn, int datasetIdx ); //
|
||||
virtual void writeDatasetRunParams( FileStorage& fs, int datasetIdx ) const;
|
||||
virtual void setDefaultDatasetRunParams( int datasetIdx );
|
||||
virtual void readDefaultRunParams( FileNode &fn );
|
||||
virtual void writeDefaultRunParams( FileStorage &fs ) const;
|
||||
|
||||
virtual void readAlgorithm();
|
||||
virtual void processRunParamsFile() {}
|
||||
virtual void runDatasetTest( const vector<Mat> &imgs, const vector<Mat> &Hs, int di, int &progress );
|
||||
|
||||
virtual void writePlotData( int di ) const;
|
||||
void calculatePlotData( vector<vector<DMatch> > &allMatches, vector<vector<uchar> > &allCorrectMatchesMask, int di );
|
||||
|
||||
struct Quality
|
||||
{
|
||||
float recall;
|
||||
float precision;
|
||||
};
|
||||
vector<vector<Quality> > calcQuality;
|
||||
vector<vector<Quality> > calcDatasetQuality;
|
||||
|
||||
struct CommonRunParams
|
||||
{
|
||||
string keypontsFilename;
|
||||
bool projectKeypointsFrom1Image;
|
||||
int matchFilter; // not used now
|
||||
bool isActiveParams;
|
||||
};
|
||||
vector<CommonRunParams> commRunParams;
|
||||
|
||||
Ptr<GenericDescriptorMatch> specificDescMatcher;
|
||||
Ptr<GenericDescriptorMatch> defaultDescMatcher;
|
||||
|
||||
CommonRunParams commRunParamsDefault;
|
||||
string matcherName;
|
||||
};
|
||||
|
||||
string DescriptorQualityEvaluator::getRunParamsFilename() const
|
||||
{
|
||||
return data_path + DESCRIPTORS_DIR + algName + PARAMS_POSTFIX;
|
||||
}
|
||||
|
||||
string DescriptorQualityEvaluator::getResultsFilename() const
|
||||
{
|
||||
return data_path + DESCRIPTORS_DIR + algName + RES_POSTFIX;
|
||||
}
|
||||
|
||||
string DescriptorQualityEvaluator::getPlotPath() const
|
||||
{
|
||||
return data_path + DESCRIPTORS_DIR + "plots/";
|
||||
}
|
||||
|
||||
void DescriptorQualityEvaluator::calcQualityClear( int datasetIdx )
|
||||
{
|
||||
calcQuality[datasetIdx].clear();
|
||||
}
|
||||
|
||||
bool DescriptorQualityEvaluator::isCalcQualityEmpty( int datasetIdx ) const
|
||||
{
|
||||
return calcQuality[datasetIdx].empty();
|
||||
}
|
||||
|
||||
void DescriptorQualityEvaluator::readDefaultRunParams (FileNode &fn)
|
||||
{
|
||||
if (! fn.empty() )
|
||||
{
|
||||
commRunParamsDefault.projectKeypointsFrom1Image = (int)fn[PROJECT_KEYPOINTS_FROM_1IMAGE] != 0;
|
||||
commRunParamsDefault.matchFilter = (int)fn[MATCH_FILTER];
|
||||
defaultDescMatcher->read (fn);
|
||||
}
|
||||
}
|
||||
|
||||
void DescriptorQualityEvaluator::writeDefaultRunParams (FileStorage &fs) const
|
||||
{
|
||||
fs << PROJECT_KEYPOINTS_FROM_1IMAGE << commRunParamsDefault.projectKeypointsFrom1Image;
|
||||
fs << MATCH_FILTER << commRunParamsDefault.matchFilter;
|
||||
defaultDescMatcher->write (fs);
|
||||
}
|
||||
|
||||
void DescriptorQualityEvaluator::readDatasetRunParams( FileNode& fn, int datasetIdx )
|
||||
{
|
||||
commRunParams[datasetIdx].isActiveParams = (int)fn[IS_ACTIVE_PARAMS] != 0;
|
||||
if (commRunParams[datasetIdx].isActiveParams)
|
||||
{
|
||||
commRunParams[datasetIdx].keypontsFilename = (string)fn[KEYPOINTS_FILENAME];
|
||||
commRunParams[datasetIdx].projectKeypointsFrom1Image = (int)fn[PROJECT_KEYPOINTS_FROM_1IMAGE] != 0;
|
||||
commRunParams[datasetIdx].matchFilter = (int)fn[MATCH_FILTER];
|
||||
specificDescMatcher->read (fn);
|
||||
}
|
||||
else
|
||||
{
|
||||
setDefaultDatasetRunParams(datasetIdx);
|
||||
}
|
||||
}
|
||||
|
||||
void DescriptorQualityEvaluator::writeDatasetRunParams( FileStorage& fs, int datasetIdx ) const
|
||||
{
|
||||
fs << IS_ACTIVE_PARAMS << commRunParams[datasetIdx].isActiveParams;
|
||||
fs << KEYPOINTS_FILENAME << commRunParams[datasetIdx].keypontsFilename;
|
||||
fs << PROJECT_KEYPOINTS_FROM_1IMAGE << commRunParams[datasetIdx].projectKeypointsFrom1Image;
|
||||
fs << MATCH_FILTER << commRunParams[datasetIdx].matchFilter;
|
||||
|
||||
defaultDescMatcher->write (fs);
|
||||
}
|
||||
|
||||
void DescriptorQualityEvaluator::setDefaultDatasetRunParams( int datasetIdx )
|
||||
{
|
||||
commRunParams[datasetIdx] = commRunParamsDefault;
|
||||
commRunParams[datasetIdx].keypontsFilename = "SURF_" + DATASET_NAMES[datasetIdx] + ".xml.gz";
|
||||
}
|
||||
|
||||
void DescriptorQualityEvaluator::writePlotData( int di ) const
|
||||
{
|
||||
stringstream filename;
|
||||
filename << getPlotPath() << algName << "_" << DATASET_NAMES[di] << ".csv";
|
||||
FILE *file = fopen (filename.str().c_str(), "w");
|
||||
size_t size = calcDatasetQuality[di].size();
|
||||
for (size_t i=0;i<size;i++)
|
||||
{
|
||||
fprintf( file, "%f, %f\n", 1 - calcDatasetQuality[di][i].precision, calcDatasetQuality[di][i].recall);
|
||||
}
|
||||
fclose( file );
|
||||
}
|
||||
|
||||
void DescriptorQualityEvaluator::readAlgorithm( )
|
||||
{
|
||||
defaultDescMatcher = GenericDescriptorMatcher::create( algName );
|
||||
specificDescMatcher = GenericDescriptorMatcher::create( algName );
|
||||
|
||||
if( !defaultDescMatcher )
|
||||
{
|
||||
Ptr<DescriptorExtractor> extractor = DescriptorExtractor::create( algName );
|
||||
Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create( matcherName );
|
||||
defaultDescMatcher = makePtr<VectorDescriptorMatch>( extractor, matcher );
|
||||
specificDescMatcher = makePtr<VectorDescriptorMatch>( extractor, matcher );
|
||||
|
||||
if( !extractor || !matcher )
|
||||
{
|
||||
printf("Algorithm can not be read\n");
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DescriptorQualityEvaluator::calculatePlotData( vector<vector<DMatch> > &allMatches, vector<vector<uchar> > &allCorrectMatchesMask, int di )
|
||||
{
|
||||
vector<Point2f> recallPrecisionCurve;
|
||||
computeRecallPrecisionCurve( allMatches, allCorrectMatchesMask, recallPrecisionCurve );
|
||||
|
||||
calcDatasetQuality[di].clear();
|
||||
const float resultPrecision = 0.5;
|
||||
bool isResultCalculated = false;
|
||||
const double eps = 1e-2;
|
||||
|
||||
Quality initQuality;
|
||||
initQuality.recall = 0;
|
||||
initQuality.precision = 0;
|
||||
calcDatasetQuality[di].push_back( initQuality );
|
||||
|
||||
for( size_t i=0;i<recallPrecisionCurve.size();i++ )
|
||||
{
|
||||
Quality quality;
|
||||
quality.recall = recallPrecisionCurve[i].y;
|
||||
quality.precision = 1 - recallPrecisionCurve[i].x;
|
||||
Quality back = calcDatasetQuality[di].back();
|
||||
|
||||
if( fabs( quality.recall - back.recall ) < eps && fabs( quality.precision - back.precision ) < eps )
|
||||
continue;
|
||||
|
||||
calcDatasetQuality[di].push_back( quality );
|
||||
|
||||
if( !isResultCalculated && quality.precision < resultPrecision )
|
||||
{
|
||||
for(int ci=0;ci<TEST_CASE_COUNT;ci++)
|
||||
{
|
||||
calcQuality[di][ci].recall = quality.recall;
|
||||
calcQuality[di][ci].precision = quality.precision;
|
||||
}
|
||||
isResultCalculated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DescriptorQualityEvaluator::runDatasetTest (const vector<Mat> &imgs, const vector<Mat> &Hs, int di, int &progress)
|
||||
{
|
||||
FileStorage keypontsFS( data_path + KEYPOINTS_DIR + commRunParams[di].keypontsFilename, FileStorage::READ );
|
||||
if( !keypontsFS.isOpened())
|
||||
{
|
||||
calcQuality[di].clear();
|
||||
printf( "keypoints from file %s can not be read\n", commRunParams[di].keypontsFilename.c_str() );
|
||||
return;
|
||||
}
|
||||
|
||||
Ptr<GenericDescriptorMatcher> descMatch = commRunParams[di].isActiveParams ? specificDescMatcher : defaultDescMatcher;
|
||||
calcQuality[di].resize(TEST_CASE_COUNT);
|
||||
|
||||
vector<KeyPoint> keypoints1;
|
||||
readKeypoints( keypontsFS, keypoints1, 0);
|
||||
|
||||
int progressCount = DATASETS_COUNT*TEST_CASE_COUNT;
|
||||
|
||||
vector<vector<DMatch> > allMatches1to2;
|
||||
vector<vector<uchar> > allCorrectMatchesMask;
|
||||
for( int ci = 0; ci < TEST_CASE_COUNT; ci++ )
|
||||
{
|
||||
progress = update_progress( testName, progress, di*TEST_CASE_COUNT + ci + 1, progressCount, 0 );
|
||||
|
||||
vector<KeyPoint> keypoints2;
|
||||
if( commRunParams[di].projectKeypointsFrom1Image )
|
||||
{
|
||||
// TODO need to test function calcKeyPointProjections
|
||||
calcKeyPointProjections( keypoints1, Hs[ci], keypoints2 );
|
||||
filterKeyPointsByImageSize( keypoints2, imgs[ci+1].size() );
|
||||
}
|
||||
else
|
||||
readKeypoints( keypontsFS, keypoints2, ci+1 );
|
||||
// TODO if( commRunParams[di].matchFilter )
|
||||
|
||||
vector<vector<DMatch> > matches1to2;
|
||||
vector<vector<uchar> > correctMatchesMask;
|
||||
vector<Point2f> recallPrecisionCurve; // not used because we need recallPrecisionCurve for
|
||||
// all images in dataset
|
||||
evaluateGenericDescriptorMatcher( imgs[0], imgs[ci+1], Hs[ci], keypoints1, keypoints2,
|
||||
&matches1to2, &correctMatchesMask, recallPrecisionCurve,
|
||||
descMatch );
|
||||
allMatches1to2.insert( allMatches1to2.end(), matches1to2.begin(), matches1to2.end() );
|
||||
allCorrectMatchesMask.insert( allCorrectMatchesMask.end(), correctMatchesMask.begin(), correctMatchesMask.end() );
|
||||
}
|
||||
|
||||
calculatePlotData( allMatches1to2, allCorrectMatchesMask, di );
|
||||
}
|
||||
|
||||
//--------------------------------- Calonder descriptor test --------------------------------------------
|
||||
class CalonderDescriptorQualityEvaluator : public DescriptorQualityEvaluator
|
||||
{
|
||||
public:
|
||||
CalonderDescriptorQualityEvaluator() :
|
||||
DescriptorQualityEvaluator( "Calonder", "quality-descriptor-calonder") {}
|
||||
virtual void readAlgorithm( )
|
||||
{
|
||||
string classifierFile = data_path + "/features2d/calonder_classifier.rtc";
|
||||
Ptr<DescriptorExtractor> extractor = makePtr<CalonderDescriptorExtractor<float> >( classifierFile );
|
||||
defaultDescMatcher = makePtr<VectorDescriptorMatch>(
|
||||
extractor,
|
||||
makePtr<BFMatcher>(extractor->defaultNorm()));
|
||||
specificDescMatcher = defaultDescMatcher;
|
||||
}
|
||||
};
|
||||
|
||||
//--------------------------------- One Way descriptor test --------------------------------------------
|
||||
class OneWayDescriptorQualityTest : public DescriptorQualityEvaluator
|
||||
{
|
||||
public:
|
||||
OneWayDescriptorQualityTest() :
|
||||
DescriptorQualityEvaluator("ONEWAY", "quality-descriptor-one-way")
|
||||
{
|
||||
}
|
||||
protected:
|
||||
virtual void processRunParamsFile ();
|
||||
virtual void writeDatasetRunParams( FileStorage& fs, int datasetIdx ) const;
|
||||
};
|
||||
|
||||
void OneWayDescriptorQualityTest::processRunParamsFile ()
|
||||
{
|
||||
string filename = getRunParamsFilename();
|
||||
FileStorage fs = FileStorage (filename, FileStorage::READ);
|
||||
FileNode fn = fs.getFirstTopLevelNode();
|
||||
fn = fn[DEFAULT_PARAMS];
|
||||
|
||||
string pcaFilename = data_path + (string)fn["pcaFilename"];
|
||||
string trainPath = data_path + (string)fn["trainPath"];
|
||||
string trainImagesList = (string)fn["trainImagesList"];
|
||||
int patch_width = fn["patchWidth"];
|
||||
int patch_height = fn["patchHeight"];
|
||||
Size patchSize = cvSize (patch_width, patch_height);
|
||||
int poseCount = fn["poseCount"];
|
||||
|
||||
if (trainImagesList.length () == 0 )
|
||||
return;
|
||||
|
||||
fs.release ();
|
||||
|
||||
readAllDatasetsRunParams();
|
||||
|
||||
Ptr<OneWayDescriptorBase> base(
|
||||
new OneWayDescriptorBase(patchSize, poseCount, pcaFilename,
|
||||
trainPath, trainImagesList));
|
||||
|
||||
Ptr<OneWayDescriptorMatch> match = makePtr<OneWayDescriptorMatch>();
|
||||
match->initialize( OneWayDescriptorMatch::Params (), base );
|
||||
defaultDescMatcher = match;
|
||||
writeAllDatasetsRunParams();
|
||||
}
|
||||
|
||||
void OneWayDescriptorQualityTest::writeDatasetRunParams( FileStorage& fs, int datasetIdx ) const
|
||||
{
|
||||
fs << IS_ACTIVE_PARAMS << commRunParams[datasetIdx].isActiveParams;
|
||||
fs << KEYPOINTS_FILENAME << commRunParams[datasetIdx].keypontsFilename;
|
||||
fs << PROJECT_KEYPOINTS_FROM_1IMAGE << commRunParams[datasetIdx].projectKeypointsFrom1Image;
|
||||
fs << MATCH_FILTER << commRunParams[datasetIdx].matchFilter;
|
||||
}
|
||||
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
if( argc != 2 )
|
||||
{
|
||||
cout << "Format: " << argv[0] << " testdata path (path to testdata/cv)" << endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
data_path = argv[1];
|
||||
#ifdef WIN32
|
||||
if( *data_path.rbegin() != '\\' )
|
||||
data_path = data_path + "\\";
|
||||
#else
|
||||
if( *data_path.rbegin() != '/' )
|
||||
data_path = data_path + "/";
|
||||
#endif
|
||||
|
||||
Ptr<BaseQualityEvaluator> evals[] =
|
||||
{
|
||||
makePtr<DetectorQualityEvaluator>( "FAST", "quality-detector-fast" ),
|
||||
makePtr<DetectorQualityEvaluator>( "GFTT", "quality-detector-gftt" ),
|
||||
makePtr<DetectorQualityEvaluator>( "HARRIS", "quality-detector-harris" ),
|
||||
makePtr<DetectorQualityEvaluator>( "MSER", "quality-detector-mser" ),
|
||||
makePtr<DetectorQualityEvaluator>( "STAR", "quality-detector-star" ),
|
||||
makePtr<DetectorQualityEvaluator>( "SIFT", "quality-detector-sift" ),
|
||||
makePtr<DetectorQualityEvaluator>( "SURF", "quality-detector-surf" ),
|
||||
|
||||
makePtr<DescriptorQualityEvaluator>( "SIFT", "quality-descriptor-sift", "BruteForce" ),
|
||||
makePtr<DescriptorQualityEvaluator>( "SURF", "quality-descriptor-surf", "BruteForce" ),
|
||||
makePtr<DescriptorQualityEvaluator>( "FERN", "quality-descriptor-fern"),
|
||||
makePtr<CalonderDescriptorQualityEvaluator>()
|
||||
};
|
||||
|
||||
for( size_t i = 0; i < sizeof(evals)/sizeof(evals[0]); i++ )
|
||||
{
|
||||
evals[i]->run();
|
||||
cout << endl;
|
||||
}
|
||||
}
|
||||
@@ -1,346 +0,0 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// Intel License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of Intel Corporation may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "opencv2/core/utility.hpp"
|
||||
#include "opencv2/imgproc.hpp"
|
||||
#include "opencv2/highgui.hpp"
|
||||
#include "opencv2/features2d.hpp"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <limits>
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
|
||||
/*
|
||||
The algorithm:
|
||||
|
||||
for each tested combination of detector+descriptor+matcher:
|
||||
|
||||
create detector, descriptor and matcher,
|
||||
load their params if they are there, otherwise use the default ones and save them
|
||||
|
||||
for each dataset:
|
||||
|
||||
load reference image
|
||||
detect keypoints in it, compute descriptors
|
||||
|
||||
for each transformed image:
|
||||
load the image
|
||||
load the transformation matrix
|
||||
detect keypoints in it too, compute descriptors
|
||||
|
||||
find matches
|
||||
transform keypoints from the first image using the ground-truth matrix
|
||||
|
||||
compute the number of matched keypoints, i.e. for each pair (i,j) found by a matcher compare
|
||||
j-th keypoint from the second image with the transformed i-th keypoint. If they are close, +1.
|
||||
|
||||
so, we have:
|
||||
N - number of keypoints in the first image that are also visible
|
||||
(after transformation) on the second image
|
||||
|
||||
N1 - number of keypoints in the first image that have been matched.
|
||||
|
||||
n - number of the correct matches found by the matcher
|
||||
|
||||
n/N1 - precision
|
||||
n/N - recall (?)
|
||||
|
||||
we store (N, n/N1, n/N) (where N is stored primarily for tuning the detector's thresholds,
|
||||
in order to semi-equalize their keypoints counts)
|
||||
|
||||
*/
|
||||
|
||||
typedef Vec3f TVec; // (N, n/N1, n/N) - see above
|
||||
|
||||
static void saveloadDDM( const string& params_filename,
|
||||
Ptr<FeatureDetector>& detector,
|
||||
Ptr<DescriptorExtractor>& descriptor,
|
||||
Ptr<DescriptorMatcher>& matcher )
|
||||
{
|
||||
FileStorage fs(params_filename, FileStorage::READ);
|
||||
if( fs.isOpened() )
|
||||
{
|
||||
detector->read(fs["detector"]);
|
||||
descriptor->read(fs["descriptor"]);
|
||||
matcher->read(fs["matcher"]);
|
||||
}
|
||||
else
|
||||
{
|
||||
fs.open(params_filename, FileStorage::WRITE);
|
||||
fs << "detector" << "{";
|
||||
detector->write(fs);
|
||||
fs << "}" << "descriptor" << "{";
|
||||
descriptor->write(fs);
|
||||
fs << "}" << "matcher" << "{";
|
||||
matcher->write(fs);
|
||||
fs << "}";
|
||||
}
|
||||
}
|
||||
|
||||
static Mat loadMat(const string& fsname)
|
||||
{
|
||||
FileStorage fs(fsname, FileStorage::READ);
|
||||
Mat m;
|
||||
fs.getFirstTopLevelNode() >> m;
|
||||
return m;
|
||||
}
|
||||
|
||||
static void transformKeypoints( const vector<KeyPoint>& kp,
|
||||
vector<vector<Point2f> >& contours,
|
||||
const Mat& H )
|
||||
{
|
||||
const float scale = 256.f;
|
||||
size_t i, n = kp.size();
|
||||
contours.resize(n);
|
||||
vector<Point> temp;
|
||||
|
||||
for( i = 0; i < n; i++ )
|
||||
{
|
||||
ellipse2Poly(Point2f(kp[i].pt.x*scale, kp[i].pt.y*scale),
|
||||
Size2f(kp[i].size*scale, kp[i].size*scale),
|
||||
0, 0, 360, 12, temp);
|
||||
Mat(temp).convertTo(contours[i], CV_32F, 1./scale);
|
||||
perspectiveTransform(contours[i], contours[i], H);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static TVec proccessMatches( Size imgsize,
|
||||
const vector<DMatch>& matches,
|
||||
const vector<vector<Point2f> >& kp1t_contours,
|
||||
const vector<vector<Point2f> >& kp_contours,
|
||||
double overlapThreshold )
|
||||
{
|
||||
const double visibilityThreshold = 0.6;
|
||||
|
||||
// 1. [preprocessing] find bounding rect for each element of kp1t_contours and kp_contours.
|
||||
// 2. [cross-check] for each DMatch (iK, i1)
|
||||
// update best_match[i1] using DMatch::distance.
|
||||
// 3. [compute overlapping] for each i1 (keypoint from the first image) do:
|
||||
// if i1-th keypoint is outside of image, skip it
|
||||
// increment N
|
||||
// if best_match[i1] is initialized, increment N1
|
||||
// if kp_contours[best_match[i1]] and kp1t_contours[i1] overlap by overlapThreshold*100%,
|
||||
// increment n. Use bounding rects to speedup this step
|
||||
|
||||
int i, size1 = (int)kp1t_contours.size(), size = (int)kp_contours.size(), msize = (int)matches.size();
|
||||
vector<DMatch> best_match(size1);
|
||||
vector<Rect> rects1(size1), rects(size);
|
||||
|
||||
// proprocess
|
||||
for( i = 0; i < size1; i++ )
|
||||
rects1[i] = boundingRect(kp1t_contours[i]);
|
||||
|
||||
for( i = 0; i < size; i++ )
|
||||
rects[i] = boundingRect(kp_contours[i]);
|
||||
|
||||
// cross-check
|
||||
for( i = 0; i < msize; i++ )
|
||||
{
|
||||
DMatch m = matches[i];
|
||||
int i1 = m.trainIdx, iK = m.queryIdx;
|
||||
CV_Assert( 0 <= i1 && i1 < size1 && 0 <= iK && iK < size );
|
||||
if( best_match[i1].trainIdx < 0 || best_match[i1].distance > m.distance )
|
||||
best_match[i1] = m;
|
||||
}
|
||||
|
||||
int N = 0, N1 = 0, n = 0;
|
||||
|
||||
// overlapping
|
||||
for( i = 0; i < size1; i++ )
|
||||
{
|
||||
int i1 = i, iK = best_match[i].queryIdx;
|
||||
if( iK >= 0 )
|
||||
N1++;
|
||||
|
||||
Rect r = rects1[i] & Rect(0, 0, imgsize.width, imgsize.height);
|
||||
if( r.area() < visibilityThreshold*rects1[i].area() )
|
||||
continue;
|
||||
N++;
|
||||
|
||||
if( iK < 0 || (rects1[i1] & rects[iK]).area() == 0 )
|
||||
continue;
|
||||
|
||||
double n_area = intersectConvexConvex(kp1t_contours[i1], kp_contours[iK], noArray(), true);
|
||||
if( n_area == 0 )
|
||||
continue;
|
||||
|
||||
double area1 = contourArea(kp1t_contours[i1], false);
|
||||
double area = contourArea(kp_contours[iK], false);
|
||||
|
||||
double ratio = n_area/(area1 + area - n_area);
|
||||
n += ratio >= overlapThreshold;
|
||||
}
|
||||
|
||||
return TVec((float)N, (float)n/std::max(N1, 1), (float)n/std::max(N, 1));
|
||||
}
|
||||
|
||||
|
||||
static void saveResults(const string& dir, const string& name, const string& dsname,
|
||||
const vector<TVec>& results, const int* xvals)
|
||||
{
|
||||
string fname1 = format("%s%s_%s_precision.csv", dir.c_str(), name.c_str(), dsname.c_str());
|
||||
string fname2 = format("%s%s_%s_recall.csv", dir.c_str(), name.c_str(), dsname.c_str());
|
||||
FILE* f1 = fopen(fname1.c_str(), "wt");
|
||||
FILE* f2 = fopen(fname2.c_str(), "wt");
|
||||
|
||||
for( size_t i = 0; i < results.size(); i++ )
|
||||
{
|
||||
fprintf(f1, "%d, %.1f\n", xvals[i], results[i][1]*100);
|
||||
fprintf(f2, "%d, %.1f\n", xvals[i], results[i][2]*100);
|
||||
}
|
||||
fclose(f1);
|
||||
fclose(f2);
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
static const char* ddms[] =
|
||||
{
|
||||
"ORBX_BF", "ORB", "ORB", "BruteForce-Hamming",
|
||||
//"ORB_BF", "ORB", "ORB", "BruteForce-Hamming",
|
||||
//"ORB3_BF", "ORB", "ORB", "BruteForce-Hamming(2)",
|
||||
//"ORB4_BF", "ORB", "ORB", "BruteForce-Hamming(2)",
|
||||
//"ORB_LSH", "ORB", "ORB", "LSH"
|
||||
//"SURF_BF", "SURF", "SURF", "BruteForce",
|
||||
0
|
||||
};
|
||||
|
||||
static const char* datasets[] =
|
||||
{
|
||||
"bark", "bikes", "boat", "graf", "leuven", "trees", "ubc", "wall", 0
|
||||
};
|
||||
|
||||
static const int imgXVals[] = { 2, 3, 4, 5, 6 }; // if scale, blur or light changes
|
||||
static const int viewpointXVals[] = { 20, 30, 40, 50, 60 }; // if viewpoint changes
|
||||
static const int jpegXVals[] = { 60, 80, 90, 95, 98 }; // if jpeg compression
|
||||
|
||||
const double overlapThreshold = 0.6;
|
||||
|
||||
vector<vector<vector<TVec> > > results; // indexed as results[ddm][dataset][testcase]
|
||||
|
||||
string dataset_dir = string(getenv("OPENCV_TEST_DATA_PATH")) +
|
||||
"/cv/detectors_descriptors_evaluation/images_datasets";
|
||||
|
||||
string dir=argc > 1 ? argv[1] : ".";
|
||||
|
||||
if( dir[dir.size()-1] != '\\' && dir[dir.size()-1] != '/' )
|
||||
dir += "/";
|
||||
|
||||
int result = system(("mkdir " + dir).c_str());
|
||||
CV_Assert(result == 0);
|
||||
|
||||
for( int i = 0; ddms[i*4] != 0; i++ )
|
||||
{
|
||||
const char* name = ddms[i*4];
|
||||
const char* detector_name = ddms[i*4+1];
|
||||
const char* descriptor_name = ddms[i*4+2];
|
||||
const char* matcher_name = ddms[i*4+3];
|
||||
string params_filename = dir + string(name) + "_params.yml";
|
||||
|
||||
cout << "Testing " << name << endl;
|
||||
|
||||
Ptr<FeatureDetector> detector = FeatureDetector::create(detector_name);
|
||||
Ptr<DescriptorExtractor> descriptor = DescriptorExtractor::create(descriptor_name);
|
||||
Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create(matcher_name);
|
||||
|
||||
saveloadDDM( params_filename, detector, descriptor, matcher );
|
||||
|
||||
results.push_back(vector<vector<TVec> >());
|
||||
|
||||
for( int j = 0; datasets[j] != 0; j++ )
|
||||
{
|
||||
const char* dsname = datasets[j];
|
||||
|
||||
cout << "\ton " << dsname << " ";
|
||||
cout.flush();
|
||||
|
||||
const int* xvals = strcmp(dsname, "ubc") == 0 ? jpegXVals :
|
||||
strcmp(dsname, "graf") == 0 || strcmp(dsname, "wall") == 0 ? viewpointXVals : imgXVals;
|
||||
|
||||
vector<KeyPoint> kp1, kp;
|
||||
vector<DMatch> matches;
|
||||
vector<vector<Point2f> > kp1t_contours, kp_contours;
|
||||
Mat desc1, desc;
|
||||
|
||||
Mat img1 = imread(format("%s/%s/img1.png", dataset_dir.c_str(), dsname), 0);
|
||||
CV_Assert( !img1.empty() );
|
||||
|
||||
detector->detect(img1, kp1);
|
||||
descriptor->compute(img1, kp1, desc1);
|
||||
|
||||
results[i].push_back(vector<TVec>());
|
||||
|
||||
for( int k = 2; ; k++ )
|
||||
{
|
||||
cout << ".";
|
||||
cout.flush();
|
||||
Mat imgK = imread(format("%s/%s/img%d.png", dataset_dir.c_str(), dsname, k), 0);
|
||||
if( imgK.empty() )
|
||||
break;
|
||||
|
||||
detector->detect(imgK, kp);
|
||||
descriptor->compute(imgK, kp, desc);
|
||||
matcher->match( desc, desc1, matches );
|
||||
|
||||
Mat H = loadMat(format("%s/%s/H1to%dp.xml", dataset_dir.c_str(), dsname, k));
|
||||
|
||||
transformKeypoints( kp1, kp1t_contours, H );
|
||||
transformKeypoints( kp, kp_contours, Mat::eye(3, 3, CV_64F));
|
||||
|
||||
TVec r = proccessMatches( imgK.size(), matches, kp1t_contours, kp_contours, overlapThreshold );
|
||||
results[i][j].push_back(r);
|
||||
}
|
||||
|
||||
saveResults(dir, name, dsname, results[i][j], xvals);
|
||||
cout << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "opencv2/highgui.hpp"
|
||||
#include "opencv2/legacy.hpp"
|
||||
#include "opencv2/ml.hpp"
|
||||
|
||||
using namespace cv;
|
||||
|
||||
@@ -19,8 +19,6 @@ int main( int /*argc*/, char** /*argv*/ )
|
||||
Mat labels;
|
||||
Mat img = Mat::zeros( Size( 500, 500 ), CV_8UC3 );
|
||||
Mat sample( 1, 2, CV_32FC1 );
|
||||
CvEM em_model;
|
||||
CvEMParams params;
|
||||
|
||||
samples = samples.reshape(2, 0);
|
||||
for( i = 0; i < N; i++ )
|
||||
@@ -35,37 +33,10 @@ int main( int /*argc*/, char** /*argv*/ )
|
||||
}
|
||||
samples = samples.reshape(1, 0);
|
||||
|
||||
// initialize model parameters
|
||||
params.covs = NULL;
|
||||
params.means = NULL;
|
||||
params.weights = NULL;
|
||||
params.probs = NULL;
|
||||
params.nclusters = N;
|
||||
params.cov_mat_type = CvEM::COV_MAT_SPHERICAL;
|
||||
params.start_step = CvEM::START_AUTO_STEP;
|
||||
params.term_crit.max_iter = 300;
|
||||
params.term_crit.epsilon = 0.1;
|
||||
params.term_crit.type = TermCriteria::COUNT|TermCriteria::EPS;
|
||||
|
||||
// cluster the data
|
||||
em_model.train( samples, Mat(), params, &labels );
|
||||
EM em_model(N, EM::COV_MAT_SPHERICAL, TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 300, 0.1));
|
||||
em_model.train( samples, noArray(), labels, noArray() );
|
||||
|
||||
#if 0
|
||||
// the piece of code shows how to repeatedly optimize the model
|
||||
// with less-constrained parameters
|
||||
//(COV_MAT_DIAGONAL instead of COV_MAT_SPHERICAL)
|
||||
// when the output of the first stage is used as input for the second one.
|
||||
CvEM em_model2;
|
||||
params.cov_mat_type = CvEM::COV_MAT_DIAGONAL;
|
||||
params.start_step = CvEM::START_E_STEP;
|
||||
params.means = em_model.get_means();
|
||||
params.covs = em_model.get_covs();
|
||||
params.weights = em_model.get_weights();
|
||||
|
||||
em_model2.train( samples, Mat(), params, &labels );
|
||||
// to use em_model2, replace em_model.predict()
|
||||
// with em_model2.predict() below
|
||||
#endif
|
||||
// classify every image pixel
|
||||
for( i = 0; i < img.rows; i++ )
|
||||
{
|
||||
@@ -73,7 +44,7 @@ int main( int /*argc*/, char** /*argv*/ )
|
||||
{
|
||||
sample.at<float>(0) = (float)j;
|
||||
sample.at<float>(1) = (float)i;
|
||||
int response = cvRound(em_model.predict( sample ));
|
||||
int response = cvRound(em_model.predict( sample )[1]);
|
||||
Scalar c = colors[response];
|
||||
|
||||
circle( img, Point(j, i), 1, c*0.75, FILLED );
|
||||
|
||||
|
Before Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 30 KiB |
@@ -1,216 +0,0 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
// This file originates from the openFABMAP project:
|
||||
// [http://code.google.com/p/openfabmap/]
|
||||
//
|
||||
// For published work which uses all or part of OpenFABMAP, please cite:
|
||||
// [http://ieeexplore.ieee.org/xpl/articleDetails.jsp?arnumber=6224843]
|
||||
//
|
||||
// Original Algorithm by Mark Cummins and Paul Newman:
|
||||
// [http://ijr.sagepub.com/content/27/6/647.short]
|
||||
// [http://ieeexplore.ieee.org/xpl/articleDetails.jsp?arnumber=5613942]
|
||||
// [http://ijr.sagepub.com/content/30/9/1100.abstract]
|
||||
//
|
||||
// License Agreement
|
||||
//
|
||||
// Copyright (C) 2012 Arren Glover [aj.glover@qut.edu.au] and
|
||||
// Will Maddern [w.maddern@qut.edu.au], all rights reserved.
|
||||
//
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "opencv2/contrib.hpp"
|
||||
#include "opencv2/highgui.hpp"
|
||||
#include "opencv2/nonfree.hpp"
|
||||
|
||||
using namespace cv;
|
||||
using namespace std;
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
|
||||
/*
|
||||
|
||||
Note: the vocabulary and training data is specifically made for this openCV
|
||||
example. It is not reccomended for use with other datasets as it is
|
||||
intentionally small to reduce baggage in the openCV project.
|
||||
|
||||
A new vocabulary can be generated using the supplied BOWMSCtrainer (or other
|
||||
clustering method such as K-means
|
||||
|
||||
New training data can be generated by extracting bag-of-words using the
|
||||
openCV BOWImgDescriptorExtractor class.
|
||||
|
||||
vocabulary, chow-liu tree, training data, and test data can all be saved and
|
||||
loaded using openCV's FileStorage class and it is not necessary to generate
|
||||
data each time as done in this example
|
||||
|
||||
*/
|
||||
|
||||
cout << "This sample program demonstrates the FAB-MAP image matching "
|
||||
"algorithm" << endl << endl;
|
||||
|
||||
string dataDir;
|
||||
if (argc == 1) {
|
||||
dataDir = "fabmap/";
|
||||
} else if (argc == 2) {
|
||||
dataDir = string(argv[1]);
|
||||
dataDir += "/";
|
||||
} else {
|
||||
//incorrect arguments
|
||||
cout << "Usage: fabmap_sample <sample data directory>" <<
|
||||
endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
FileStorage fs;
|
||||
|
||||
//load/generate vocab
|
||||
cout << "Loading Vocabulary: " <<
|
||||
dataDir + string("vocab_small.yml") << endl << endl;
|
||||
fs.open(dataDir + string("vocab_small.yml"), FileStorage::READ);
|
||||
Mat vocab;
|
||||
fs["Vocabulary"] >> vocab;
|
||||
if (vocab.empty()) {
|
||||
cerr << "Vocabulary not found" << endl;
|
||||
return -1;
|
||||
}
|
||||
fs.release();
|
||||
|
||||
//load/generate training data
|
||||
|
||||
cout << "Loading Training Data: " <<
|
||||
dataDir + string("train_data_small.yml") << endl << endl;
|
||||
fs.open(dataDir + string("train_data_small.yml"), FileStorage::READ);
|
||||
Mat trainData;
|
||||
fs["BOWImageDescs"] >> trainData;
|
||||
if (trainData.empty()) {
|
||||
cerr << "Training Data not found" << endl;
|
||||
return -1;
|
||||
}
|
||||
fs.release();
|
||||
|
||||
//create Chow-liu tree
|
||||
cout << "Making Chow-Liu Tree from training data" << endl <<
|
||||
endl;
|
||||
of2::ChowLiuTree treeBuilder;
|
||||
treeBuilder.add(trainData);
|
||||
Mat tree = treeBuilder.make();
|
||||
|
||||
//generate test data
|
||||
cout << "Extracting Test Data from images" << endl <<
|
||||
endl;
|
||||
Ptr<FeatureDetector> detector(
|
||||
new DynamicAdaptedFeatureDetector(
|
||||
AdjusterAdapter::create("STAR"), 130, 150, 5));
|
||||
Ptr<DescriptorExtractor> extractor(
|
||||
new SurfDescriptorExtractor(1000, 4, 2, false, true));
|
||||
Ptr<DescriptorMatcher> matcher =
|
||||
DescriptorMatcher::create("FlannBased");
|
||||
|
||||
BOWImgDescriptorExtractor bide(extractor, matcher);
|
||||
bide.setVocabulary(vocab);
|
||||
|
||||
vector<string> imageNames;
|
||||
imageNames.push_back(string("stlucia_test_small0000.jpeg"));
|
||||
imageNames.push_back(string("stlucia_test_small0001.jpeg"));
|
||||
imageNames.push_back(string("stlucia_test_small0002.jpeg"));
|
||||
imageNames.push_back(string("stlucia_test_small0003.jpeg"));
|
||||
imageNames.push_back(string("stlucia_test_small0004.jpeg"));
|
||||
imageNames.push_back(string("stlucia_test_small0005.jpeg"));
|
||||
imageNames.push_back(string("stlucia_test_small0006.jpeg"));
|
||||
imageNames.push_back(string("stlucia_test_small0007.jpeg"));
|
||||
imageNames.push_back(string("stlucia_test_small0008.jpeg"));
|
||||
imageNames.push_back(string("stlucia_test_small0009.jpeg"));
|
||||
|
||||
Mat testData;
|
||||
Mat frame;
|
||||
Mat bow;
|
||||
vector<KeyPoint> kpts;
|
||||
|
||||
for(size_t i = 0; i < imageNames.size(); i++) {
|
||||
cout << dataDir + imageNames[i] << endl;
|
||||
frame = imread(dataDir + imageNames[i]);
|
||||
if(frame.empty()) {
|
||||
cerr << "Test images not found" << endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
detector->detect(frame, kpts);
|
||||
|
||||
bide.compute(frame, kpts, bow);
|
||||
|
||||
testData.push_back(bow);
|
||||
|
||||
drawKeypoints(frame, kpts, frame);
|
||||
imshow(imageNames[i], frame);
|
||||
waitKey(10);
|
||||
}
|
||||
|
||||
//run fabmap
|
||||
cout << "Running FAB-MAP algorithm" << endl <<
|
||||
endl;
|
||||
Ptr<of2::FabMap> fabmap;
|
||||
|
||||
fabmap.reset(new of2::FabMap2(tree, 0.39, 0, of2::FabMap::SAMPLED |
|
||||
of2::FabMap::CHOW_LIU));
|
||||
fabmap->addTraining(trainData);
|
||||
|
||||
vector<of2::IMatch> matches;
|
||||
fabmap->compare(testData, matches, true);
|
||||
|
||||
//display output
|
||||
Mat result_small = Mat::zeros(10, 10, CV_8UC1);
|
||||
vector<of2::IMatch>::iterator l;
|
||||
|
||||
for(l = matches.begin(); l != matches.end(); l++) {
|
||||
if(l->imgIdx < 0) {
|
||||
result_small.at<char>(l->queryIdx, l->queryIdx) =
|
||||
(char)(l->match*255);
|
||||
|
||||
} else {
|
||||
result_small.at<char>(l->queryIdx, l->imgIdx) =
|
||||
(char)(l->match*255);
|
||||
}
|
||||
}
|
||||
|
||||
Mat result_large(100, 100, CV_8UC1);
|
||||
resize(result_small, result_large, Size(500, 500), 0, 0, INTER_NEAREST);
|
||||
|
||||
cout << endl << "Press any key to exit" << endl;
|
||||
imshow("Confusion Matrix", result_large);
|
||||
waitKey();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,400 +0,0 @@
|
||||
/path/to/at/s13/2.pgm;12
|
||||
/path/to/at/s13/7.pgm;12
|
||||
/path/to/at/s13/6.pgm;12
|
||||
/path/to/at/s13/9.pgm;12
|
||||
/path/to/at/s13/5.pgm;12
|
||||
/path/to/at/s13/3.pgm;12
|
||||
/path/to/at/s13/4.pgm;12
|
||||
/path/to/at/s13/10.pgm;12
|
||||
/path/to/at/s13/8.pgm;12
|
||||
/path/to/at/s13/1.pgm;12
|
||||
/path/to/at/s17/2.pgm;16
|
||||
/path/to/at/s17/7.pgm;16
|
||||
/path/to/at/s17/6.pgm;16
|
||||
/path/to/at/s17/9.pgm;16
|
||||
/path/to/at/s17/5.pgm;16
|
||||
/path/to/at/s17/3.pgm;16
|
||||
/path/to/at/s17/4.pgm;16
|
||||
/path/to/at/s17/10.pgm;16
|
||||
/path/to/at/s17/8.pgm;16
|
||||
/path/to/at/s17/1.pgm;16
|
||||
/path/to/at/s32/2.pgm;31
|
||||
/path/to/at/s32/7.pgm;31
|
||||
/path/to/at/s32/6.pgm;31
|
||||
/path/to/at/s32/9.pgm;31
|
||||
/path/to/at/s32/5.pgm;31
|
||||
/path/to/at/s32/3.pgm;31
|
||||
/path/to/at/s32/4.pgm;31
|
||||
/path/to/at/s32/10.pgm;31
|
||||
/path/to/at/s32/8.pgm;31
|
||||
/path/to/at/s32/1.pgm;31
|
||||
/path/to/at/s10/2.pgm;9
|
||||
/path/to/at/s10/7.pgm;9
|
||||
/path/to/at/s10/6.pgm;9
|
||||
/path/to/at/s10/9.pgm;9
|
||||
/path/to/at/s10/5.pgm;9
|
||||
/path/to/at/s10/3.pgm;9
|
||||
/path/to/at/s10/4.pgm;9
|
||||
/path/to/at/s10/10.pgm;9
|
||||
/path/to/at/s10/8.pgm;9
|
||||
/path/to/at/s10/1.pgm;9
|
||||
/path/to/at/s27/2.pgm;26
|
||||
/path/to/at/s27/7.pgm;26
|
||||
/path/to/at/s27/6.pgm;26
|
||||
/path/to/at/s27/9.pgm;26
|
||||
/path/to/at/s27/5.pgm;26
|
||||
/path/to/at/s27/3.pgm;26
|
||||
/path/to/at/s27/4.pgm;26
|
||||
/path/to/at/s27/10.pgm;26
|
||||
/path/to/at/s27/8.pgm;26
|
||||
/path/to/at/s27/1.pgm;26
|
||||
/path/to/at/s5/2.pgm;4
|
||||
/path/to/at/s5/7.pgm;4
|
||||
/path/to/at/s5/6.pgm;4
|
||||
/path/to/at/s5/9.pgm;4
|
||||
/path/to/at/s5/5.pgm;4
|
||||
/path/to/at/s5/3.pgm;4
|
||||
/path/to/at/s5/4.pgm;4
|
||||
/path/to/at/s5/10.pgm;4
|
||||
/path/to/at/s5/8.pgm;4
|
||||
/path/to/at/s5/1.pgm;4
|
||||
/path/to/at/s20/2.pgm;19
|
||||
/path/to/at/s20/7.pgm;19
|
||||
/path/to/at/s20/6.pgm;19
|
||||
/path/to/at/s20/9.pgm;19
|
||||
/path/to/at/s20/5.pgm;19
|
||||
/path/to/at/s20/3.pgm;19
|
||||
/path/to/at/s20/4.pgm;19
|
||||
/path/to/at/s20/10.pgm;19
|
||||
/path/to/at/s20/8.pgm;19
|
||||
/path/to/at/s20/1.pgm;19
|
||||
/path/to/at/s30/2.pgm;29
|
||||
/path/to/at/s30/7.pgm;29
|
||||
/path/to/at/s30/6.pgm;29
|
||||
/path/to/at/s30/9.pgm;29
|
||||
/path/to/at/s30/5.pgm;29
|
||||
/path/to/at/s30/3.pgm;29
|
||||
/path/to/at/s30/4.pgm;29
|
||||
/path/to/at/s30/10.pgm;29
|
||||
/path/to/at/s30/8.pgm;29
|
||||
/path/to/at/s30/1.pgm;29
|
||||
/path/to/at/s39/2.pgm;38
|
||||
/path/to/at/s39/7.pgm;38
|
||||
/path/to/at/s39/6.pgm;38
|
||||
/path/to/at/s39/9.pgm;38
|
||||
/path/to/at/s39/5.pgm;38
|
||||
/path/to/at/s39/3.pgm;38
|
||||
/path/to/at/s39/4.pgm;38
|
||||
/path/to/at/s39/10.pgm;38
|
||||
/path/to/at/s39/8.pgm;38
|
||||
/path/to/at/s39/1.pgm;38
|
||||
/path/to/at/s35/2.pgm;34
|
||||
/path/to/at/s35/7.pgm;34
|
||||
/path/to/at/s35/6.pgm;34
|
||||
/path/to/at/s35/9.pgm;34
|
||||
/path/to/at/s35/5.pgm;34
|
||||
/path/to/at/s35/3.pgm;34
|
||||
/path/to/at/s35/4.pgm;34
|
||||
/path/to/at/s35/10.pgm;34
|
||||
/path/to/at/s35/8.pgm;34
|
||||
/path/to/at/s35/1.pgm;34
|
||||
/path/to/at/s23/2.pgm;22
|
||||
/path/to/at/s23/7.pgm;22
|
||||
/path/to/at/s23/6.pgm;22
|
||||
/path/to/at/s23/9.pgm;22
|
||||
/path/to/at/s23/5.pgm;22
|
||||
/path/to/at/s23/3.pgm;22
|
||||
/path/to/at/s23/4.pgm;22
|
||||
/path/to/at/s23/10.pgm;22
|
||||
/path/to/at/s23/8.pgm;22
|
||||
/path/to/at/s23/1.pgm;22
|
||||
/path/to/at/s4/2.pgm;3
|
||||
/path/to/at/s4/7.pgm;3
|
||||
/path/to/at/s4/6.pgm;3
|
||||
/path/to/at/s4/9.pgm;3
|
||||
/path/to/at/s4/5.pgm;3
|
||||
/path/to/at/s4/3.pgm;3
|
||||
/path/to/at/s4/4.pgm;3
|
||||
/path/to/at/s4/10.pgm;3
|
||||
/path/to/at/s4/8.pgm;3
|
||||
/path/to/at/s4/1.pgm;3
|
||||
/path/to/at/s9/2.pgm;8
|
||||
/path/to/at/s9/7.pgm;8
|
||||
/path/to/at/s9/6.pgm;8
|
||||
/path/to/at/s9/9.pgm;8
|
||||
/path/to/at/s9/5.pgm;8
|
||||
/path/to/at/s9/3.pgm;8
|
||||
/path/to/at/s9/4.pgm;8
|
||||
/path/to/at/s9/10.pgm;8
|
||||
/path/to/at/s9/8.pgm;8
|
||||
/path/to/at/s9/1.pgm;8
|
||||
/path/to/at/s37/2.pgm;36
|
||||
/path/to/at/s37/7.pgm;36
|
||||
/path/to/at/s37/6.pgm;36
|
||||
/path/to/at/s37/9.pgm;36
|
||||
/path/to/at/s37/5.pgm;36
|
||||
/path/to/at/s37/3.pgm;36
|
||||
/path/to/at/s37/4.pgm;36
|
||||
/path/to/at/s37/10.pgm;36
|
||||
/path/to/at/s37/8.pgm;36
|
||||
/path/to/at/s37/1.pgm;36
|
||||
/path/to/at/s24/2.pgm;23
|
||||
/path/to/at/s24/7.pgm;23
|
||||
/path/to/at/s24/6.pgm;23
|
||||
/path/to/at/s24/9.pgm;23
|
||||
/path/to/at/s24/5.pgm;23
|
||||
/path/to/at/s24/3.pgm;23
|
||||
/path/to/at/s24/4.pgm;23
|
||||
/path/to/at/s24/10.pgm;23
|
||||
/path/to/at/s24/8.pgm;23
|
||||
/path/to/at/s24/1.pgm;23
|
||||
/path/to/at/s19/2.pgm;18
|
||||
/path/to/at/s19/7.pgm;18
|
||||
/path/to/at/s19/6.pgm;18
|
||||
/path/to/at/s19/9.pgm;18
|
||||
/path/to/at/s19/5.pgm;18
|
||||
/path/to/at/s19/3.pgm;18
|
||||
/path/to/at/s19/4.pgm;18
|
||||
/path/to/at/s19/10.pgm;18
|
||||
/path/to/at/s19/8.pgm;18
|
||||
/path/to/at/s19/1.pgm;18
|
||||
/path/to/at/s8/2.pgm;7
|
||||
/path/to/at/s8/7.pgm;7
|
||||
/path/to/at/s8/6.pgm;7
|
||||
/path/to/at/s8/9.pgm;7
|
||||
/path/to/at/s8/5.pgm;7
|
||||
/path/to/at/s8/3.pgm;7
|
||||
/path/to/at/s8/4.pgm;7
|
||||
/path/to/at/s8/10.pgm;7
|
||||
/path/to/at/s8/8.pgm;7
|
||||
/path/to/at/s8/1.pgm;7
|
||||
/path/to/at/s21/2.pgm;20
|
||||
/path/to/at/s21/7.pgm;20
|
||||
/path/to/at/s21/6.pgm;20
|
||||
/path/to/at/s21/9.pgm;20
|
||||
/path/to/at/s21/5.pgm;20
|
||||
/path/to/at/s21/3.pgm;20
|
||||
/path/to/at/s21/4.pgm;20
|
||||
/path/to/at/s21/10.pgm;20
|
||||
/path/to/at/s21/8.pgm;20
|
||||
/path/to/at/s21/1.pgm;20
|
||||
/path/to/at/s1/2.pgm;0
|
||||
/path/to/at/s1/7.pgm;0
|
||||
/path/to/at/s1/6.pgm;0
|
||||
/path/to/at/s1/9.pgm;0
|
||||
/path/to/at/s1/5.pgm;0
|
||||
/path/to/at/s1/3.pgm;0
|
||||
/path/to/at/s1/4.pgm;0
|
||||
/path/to/at/s1/10.pgm;0
|
||||
/path/to/at/s1/8.pgm;0
|
||||
/path/to/at/s1/1.pgm;0
|
||||
/path/to/at/s7/2.pgm;6
|
||||
/path/to/at/s7/7.pgm;6
|
||||
/path/to/at/s7/6.pgm;6
|
||||
/path/to/at/s7/9.pgm;6
|
||||
/path/to/at/s7/5.pgm;6
|
||||
/path/to/at/s7/3.pgm;6
|
||||
/path/to/at/s7/4.pgm;6
|
||||
/path/to/at/s7/10.pgm;6
|
||||
/path/to/at/s7/8.pgm;6
|
||||
/path/to/at/s7/1.pgm;6
|
||||
/path/to/at/s16/2.pgm;15
|
||||
/path/to/at/s16/7.pgm;15
|
||||
/path/to/at/s16/6.pgm;15
|
||||
/path/to/at/s16/9.pgm;15
|
||||
/path/to/at/s16/5.pgm;15
|
||||
/path/to/at/s16/3.pgm;15
|
||||
/path/to/at/s16/4.pgm;15
|
||||
/path/to/at/s16/10.pgm;15
|
||||
/path/to/at/s16/8.pgm;15
|
||||
/path/to/at/s16/1.pgm;15
|
||||
/path/to/at/s36/2.pgm;35
|
||||
/path/to/at/s36/7.pgm;35
|
||||
/path/to/at/s36/6.pgm;35
|
||||
/path/to/at/s36/9.pgm;35
|
||||
/path/to/at/s36/5.pgm;35
|
||||
/path/to/at/s36/3.pgm;35
|
||||
/path/to/at/s36/4.pgm;35
|
||||
/path/to/at/s36/10.pgm;35
|
||||
/path/to/at/s36/8.pgm;35
|
||||
/path/to/at/s36/1.pgm;35
|
||||
/path/to/at/s25/2.pgm;24
|
||||
/path/to/at/s25/7.pgm;24
|
||||
/path/to/at/s25/6.pgm;24
|
||||
/path/to/at/s25/9.pgm;24
|
||||
/path/to/at/s25/5.pgm;24
|
||||
/path/to/at/s25/3.pgm;24
|
||||
/path/to/at/s25/4.pgm;24
|
||||
/path/to/at/s25/10.pgm;24
|
||||
/path/to/at/s25/8.pgm;24
|
||||
/path/to/at/s25/1.pgm;24
|
||||
/path/to/at/s14/2.pgm;13
|
||||
/path/to/at/s14/7.pgm;13
|
||||
/path/to/at/s14/6.pgm;13
|
||||
/path/to/at/s14/9.pgm;13
|
||||
/path/to/at/s14/5.pgm;13
|
||||
/path/to/at/s14/3.pgm;13
|
||||
/path/to/at/s14/4.pgm;13
|
||||
/path/to/at/s14/10.pgm;13
|
||||
/path/to/at/s14/8.pgm;13
|
||||
/path/to/at/s14/1.pgm;13
|
||||
/path/to/at/s34/2.pgm;33
|
||||
/path/to/at/s34/7.pgm;33
|
||||
/path/to/at/s34/6.pgm;33
|
||||
/path/to/at/s34/9.pgm;33
|
||||
/path/to/at/s34/5.pgm;33
|
||||
/path/to/at/s34/3.pgm;33
|
||||
/path/to/at/s34/4.pgm;33
|
||||
/path/to/at/s34/10.pgm;33
|
||||
/path/to/at/s34/8.pgm;33
|
||||
/path/to/at/s34/1.pgm;33
|
||||
/path/to/at/s11/2.pgm;10
|
||||
/path/to/at/s11/7.pgm;10
|
||||
/path/to/at/s11/6.pgm;10
|
||||
/path/to/at/s11/9.pgm;10
|
||||
/path/to/at/s11/5.pgm;10
|
||||
/path/to/at/s11/3.pgm;10
|
||||
/path/to/at/s11/4.pgm;10
|
||||
/path/to/at/s11/10.pgm;10
|
||||
/path/to/at/s11/8.pgm;10
|
||||
/path/to/at/s11/1.pgm;10
|
||||
/path/to/at/s26/2.pgm;25
|
||||
/path/to/at/s26/7.pgm;25
|
||||
/path/to/at/s26/6.pgm;25
|
||||
/path/to/at/s26/9.pgm;25
|
||||
/path/to/at/s26/5.pgm;25
|
||||
/path/to/at/s26/3.pgm;25
|
||||
/path/to/at/s26/4.pgm;25
|
||||
/path/to/at/s26/10.pgm;25
|
||||
/path/to/at/s26/8.pgm;25
|
||||
/path/to/at/s26/1.pgm;25
|
||||
/path/to/at/s18/2.pgm;17
|
||||
/path/to/at/s18/7.pgm;17
|
||||
/path/to/at/s18/6.pgm;17
|
||||
/path/to/at/s18/9.pgm;17
|
||||
/path/to/at/s18/5.pgm;17
|
||||
/path/to/at/s18/3.pgm;17
|
||||
/path/to/at/s18/4.pgm;17
|
||||
/path/to/at/s18/10.pgm;17
|
||||
/path/to/at/s18/8.pgm;17
|
||||
/path/to/at/s18/1.pgm;17
|
||||
/path/to/at/s29/2.pgm;28
|
||||
/path/to/at/s29/7.pgm;28
|
||||
/path/to/at/s29/6.pgm;28
|
||||
/path/to/at/s29/9.pgm;28
|
||||
/path/to/at/s29/5.pgm;28
|
||||
/path/to/at/s29/3.pgm;28
|
||||
/path/to/at/s29/4.pgm;28
|
||||
/path/to/at/s29/10.pgm;28
|
||||
/path/to/at/s29/8.pgm;28
|
||||
/path/to/at/s29/1.pgm;28
|
||||
/path/to/at/s33/2.pgm;32
|
||||
/path/to/at/s33/7.pgm;32
|
||||
/path/to/at/s33/6.pgm;32
|
||||
/path/to/at/s33/9.pgm;32
|
||||
/path/to/at/s33/5.pgm;32
|
||||
/path/to/at/s33/3.pgm;32
|
||||
/path/to/at/s33/4.pgm;32
|
||||
/path/to/at/s33/10.pgm;32
|
||||
/path/to/at/s33/8.pgm;32
|
||||
/path/to/at/s33/1.pgm;32
|
||||
/path/to/at/s12/2.pgm;11
|
||||
/path/to/at/s12/7.pgm;11
|
||||
/path/to/at/s12/6.pgm;11
|
||||
/path/to/at/s12/9.pgm;11
|
||||
/path/to/at/s12/5.pgm;11
|
||||
/path/to/at/s12/3.pgm;11
|
||||
/path/to/at/s12/4.pgm;11
|
||||
/path/to/at/s12/10.pgm;11
|
||||
/path/to/at/s12/8.pgm;11
|
||||
/path/to/at/s12/1.pgm;11
|
||||
/path/to/at/s6/2.pgm;5
|
||||
/path/to/at/s6/7.pgm;5
|
||||
/path/to/at/s6/6.pgm;5
|
||||
/path/to/at/s6/9.pgm;5
|
||||
/path/to/at/s6/5.pgm;5
|
||||
/path/to/at/s6/3.pgm;5
|
||||
/path/to/at/s6/4.pgm;5
|
||||
/path/to/at/s6/10.pgm;5
|
||||
/path/to/at/s6/8.pgm;5
|
||||
/path/to/at/s6/1.pgm;5
|
||||
/path/to/at/s22/2.pgm;21
|
||||
/path/to/at/s22/7.pgm;21
|
||||
/path/to/at/s22/6.pgm;21
|
||||
/path/to/at/s22/9.pgm;21
|
||||
/path/to/at/s22/5.pgm;21
|
||||
/path/to/at/s22/3.pgm;21
|
||||
/path/to/at/s22/4.pgm;21
|
||||
/path/to/at/s22/10.pgm;21
|
||||
/path/to/at/s22/8.pgm;21
|
||||
/path/to/at/s22/1.pgm;21
|
||||
/path/to/at/s15/2.pgm;14
|
||||
/path/to/at/s15/7.pgm;14
|
||||
/path/to/at/s15/6.pgm;14
|
||||
/path/to/at/s15/9.pgm;14
|
||||
/path/to/at/s15/5.pgm;14
|
||||
/path/to/at/s15/3.pgm;14
|
||||
/path/to/at/s15/4.pgm;14
|
||||
/path/to/at/s15/10.pgm;14
|
||||
/path/to/at/s15/8.pgm;14
|
||||
/path/to/at/s15/1.pgm;14
|
||||
/path/to/at/s2/2.pgm;1
|
||||
/path/to/at/s2/7.pgm;1
|
||||
/path/to/at/s2/6.pgm;1
|
||||
/path/to/at/s2/9.pgm;1
|
||||
/path/to/at/s2/5.pgm;1
|
||||
/path/to/at/s2/3.pgm;1
|
||||
/path/to/at/s2/4.pgm;1
|
||||
/path/to/at/s2/10.pgm;1
|
||||
/path/to/at/s2/8.pgm;1
|
||||
/path/to/at/s2/1.pgm;1
|
||||
/path/to/at/s31/2.pgm;30
|
||||
/path/to/at/s31/7.pgm;30
|
||||
/path/to/at/s31/6.pgm;30
|
||||
/path/to/at/s31/9.pgm;30
|
||||
/path/to/at/s31/5.pgm;30
|
||||
/path/to/at/s31/3.pgm;30
|
||||
/path/to/at/s31/4.pgm;30
|
||||
/path/to/at/s31/10.pgm;30
|
||||
/path/to/at/s31/8.pgm;30
|
||||
/path/to/at/s31/1.pgm;30
|
||||
/path/to/at/s28/2.pgm;27
|
||||
/path/to/at/s28/7.pgm;27
|
||||
/path/to/at/s28/6.pgm;27
|
||||
/path/to/at/s28/9.pgm;27
|
||||
/path/to/at/s28/5.pgm;27
|
||||
/path/to/at/s28/3.pgm;27
|
||||
/path/to/at/s28/4.pgm;27
|
||||
/path/to/at/s28/10.pgm;27
|
||||
/path/to/at/s28/8.pgm;27
|
||||
/path/to/at/s28/1.pgm;27
|
||||
/path/to/at/s40/2.pgm;39
|
||||
/path/to/at/s40/7.pgm;39
|
||||
/path/to/at/s40/6.pgm;39
|
||||
/path/to/at/s40/9.pgm;39
|
||||
/path/to/at/s40/5.pgm;39
|
||||
/path/to/at/s40/3.pgm;39
|
||||
/path/to/at/s40/4.pgm;39
|
||||
/path/to/at/s40/10.pgm;39
|
||||
/path/to/at/s40/8.pgm;39
|
||||
/path/to/at/s40/1.pgm;39
|
||||
/path/to/at/s3/2.pgm;2
|
||||
/path/to/at/s3/7.pgm;2
|
||||
/path/to/at/s3/6.pgm;2
|
||||
/path/to/at/s3/9.pgm;2
|
||||
/path/to/at/s3/5.pgm;2
|
||||
/path/to/at/s3/3.pgm;2
|
||||
/path/to/at/s3/4.pgm;2
|
||||
/path/to/at/s3/10.pgm;2
|
||||
/path/to/at/s3/8.pgm;2
|
||||
/path/to/at/s3/1.pgm;2
|
||||
/path/to/at/s38/2.pgm;37
|
||||
/path/to/at/s38/7.pgm;37
|
||||
/path/to/at/s38/6.pgm;37
|
||||
/path/to/at/s38/9.pgm;37
|
||||
/path/to/at/s38/5.pgm;37
|
||||
/path/to/at/s38/3.pgm;37
|
||||
/path/to/at/s38/4.pgm;37
|
||||
/path/to/at/s38/10.pgm;37
|
||||
/path/to/at/s38/8.pgm;37
|
||||
/path/to/at/s38/1.pgm;37
|
||||
@@ -1,163 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011. Philipp Wagner <bytefish[at]gmx[dot]de>.
|
||||
* Released to public domain under terms of the BSD Simplified license.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the organization nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* See <http://www.opensource.org/licenses/bsd-license>
|
||||
*/
|
||||
|
||||
#include "opencv2/core.hpp"
|
||||
#include "opencv2/core/utility.hpp"
|
||||
#include "opencv2/highgui.hpp"
|
||||
#include "opencv2/contrib.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
using namespace cv;
|
||||
using namespace std;
|
||||
|
||||
static Mat toGrayscale(InputArray _src) {
|
||||
Mat src = _src.getMat();
|
||||
// only allow one channel
|
||||
if(src.channels() != 1) {
|
||||
CV_Error(Error::StsBadArg, "Only Matrices with one channel are supported");
|
||||
}
|
||||
// create and return normalized image
|
||||
Mat dst;
|
||||
cv::normalize(_src, dst, 0, 255, NORM_MINMAX, CV_8UC1);
|
||||
return dst;
|
||||
}
|
||||
|
||||
static void read_csv(const string& filename, vector<Mat>& images, vector<int>& labels, char separator = ';') {
|
||||
std::ifstream file(filename.c_str(), ifstream::in);
|
||||
if (!file) {
|
||||
string error_message = "No valid input file was given, please check the given filename.";
|
||||
CV_Error(Error::StsBadArg, error_message);
|
||||
}
|
||||
string line, path, classlabel;
|
||||
while (getline(file, line)) {
|
||||
stringstream liness(line);
|
||||
getline(liness, path, separator);
|
||||
getline(liness, classlabel);
|
||||
if(!path.empty() && !classlabel.empty()) {
|
||||
images.push_back(imread(path, 0));
|
||||
labels.push_back(atoi(classlabel.c_str()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, const char *argv[]) {
|
||||
// Check for valid command line arguments, print usage
|
||||
// if no arguments were given.
|
||||
if (argc != 2) {
|
||||
cout << "usage: " << argv[0] << " <csv.ext>" << endl;
|
||||
exit(1);
|
||||
}
|
||||
// Get the path to your CSV.
|
||||
string fn_csv = string(argv[1]);
|
||||
// These vectors hold the images and corresponding labels.
|
||||
vector<Mat> images;
|
||||
vector<int> labels;
|
||||
// Read in the data. This can fail if no valid
|
||||
// input filename is given.
|
||||
try {
|
||||
read_csv(fn_csv, images, labels);
|
||||
} catch (cv::Exception& e) {
|
||||
cerr << "Error opening file \"" << fn_csv << "\". Reason: " << e.msg << endl;
|
||||
// nothing more we can do
|
||||
exit(1);
|
||||
}
|
||||
// Quit if there are not enough images for this demo.
|
||||
if(images.size() <= 1) {
|
||||
string error_message = "This demo needs at least 2 images to work. Please add more images to your data set!";
|
||||
CV_Error(Error::StsError, error_message);
|
||||
}
|
||||
// Get the height from the first image. We'll need this
|
||||
// later in code to reshape the images to their original
|
||||
// size:
|
||||
int height = images[0].rows;
|
||||
// The following lines simply get the last images from
|
||||
// your dataset and remove it from the vector. This is
|
||||
// done, so that the training data (which we learn the
|
||||
// cv::FaceRecognizer on) and the test data we test
|
||||
// the model with, do not overlap.
|
||||
Mat testSample = images[images.size() - 1];
|
||||
int testLabel = labels[labels.size() - 1];
|
||||
images.pop_back();
|
||||
labels.pop_back();
|
||||
// The following lines create an Eigenfaces model for
|
||||
// face recognition and train it with the images and
|
||||
// labels read from the given CSV file.
|
||||
// This here is a full PCA, if you just want to keep
|
||||
// 10 principal components (read Eigenfaces), then call
|
||||
// the factory method like this:
|
||||
//
|
||||
// cv::createEigenFaceRecognizer(10);
|
||||
//
|
||||
// If you want to create a FaceRecognizer with a
|
||||
// confidennce threshold, call it with:
|
||||
//
|
||||
// cv::createEigenFaceRecognizer(10, 123.0);
|
||||
//
|
||||
Ptr<FaceRecognizer> model = createEigenFaceRecognizer();
|
||||
model->train(images, labels);
|
||||
// The following line predicts the label of a given
|
||||
// test image:
|
||||
int predictedLabel = model->predict(testSample);
|
||||
//
|
||||
// To get the confidence of a prediction call the model with:
|
||||
//
|
||||
// int predictedLabel = -1;
|
||||
// double confidence = 0.0;
|
||||
// model->predict(testSample, predictedLabel, confidence);
|
||||
//
|
||||
string result_message = format("Predicted class = %d / Actual class = %d.", predictedLabel, testLabel);
|
||||
cout << result_message << endl;
|
||||
// Sometimes you'll need to get/set internal model data,
|
||||
// which isn't exposed by the public cv::FaceRecognizer.
|
||||
// Since each cv::FaceRecognizer is derived from a
|
||||
// cv::Algorithm, you can query the data.
|
||||
//
|
||||
// First we'll use it to set the threshold of the FaceRecognizer
|
||||
// to 0.0 without retraining the model. This can be useful if
|
||||
// you are evaluating the model:
|
||||
//
|
||||
model->set("threshold", 0.0);
|
||||
// Now the threshold of this model is set to 0.0. A prediction
|
||||
// now returns -1, as it's impossible to have a distance below
|
||||
// it
|
||||
predictedLabel = model->predict(testSample);
|
||||
cout << "Predicted class = " << predictedLabel << endl;
|
||||
// Here is how to get the eigenvalues of this Eigenfaces model:
|
||||
Mat eigenvalues = model->getMat("eigenvalues");
|
||||
// And we can do the same to display the Eigenvectors (read Eigenfaces):
|
||||
Mat W = model->getMat("eigenvectors");
|
||||
// From this we will display the (at most) first 10 Eigenfaces:
|
||||
for (int i = 0; i < min(10, W.cols); i++) {
|
||||
string msg = format("Eigenvalue #%d = %.5f", i, eigenvalues.at<double>(i));
|
||||
cout << msg << endl;
|
||||
// get eigenvector #i
|
||||
Mat ev = W.col(i).clone();
|
||||
// Reshape to original size & normalize to [0...255] for imshow.
|
||||
Mat grayscale = toGrayscale(ev.reshape(1, height));
|
||||
// Show the image & apply a Jet colormap for better sensing.
|
||||
Mat cgrayscale;
|
||||
applyColorMap(grayscale, cgrayscale, COLORMAP_JET);
|
||||
imshow(format("%d", i), cgrayscale);
|
||||
}
|
||||
waitKey(0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<opencv_storage>
|
||||
<nclasses>0</nclasses>
|
||||
<patchSize>31</patchSize>
|
||||
<signatureSize>INT_MAX</signatureSize>
|
||||
<nstructs>50</nstructs>
|
||||
<structSize>9</structSize>
|
||||
<nviews>1000</nviews>
|
||||
<compressionMethod>0</compressionMethod>
|
||||
</opencv_storage>
|
||||
@@ -1,128 +0,0 @@
|
||||
// demo.cpp
|
||||
//
|
||||
// Here is an example on how to use the descriptor presented in the following paper:
|
||||
// A. Alahi, R. Ortiz, and P. Vandergheynst. FREAK: Fast Retina Keypoint. In IEEE Conference on Computer Vision and Pattern Recognition, 2012.
|
||||
// CVPR 2012 Open Source Award winner
|
||||
//
|
||||
// Copyright (C) 2011-2012 Signal processing laboratory 2, EPFL,
|
||||
// Kirell Benzi (kirell.benzi@epfl.ch),
|
||||
// Raphael Ortiz (raphael.ortiz@a3.epfl.ch),
|
||||
// Alexandre Alahi (alexandre.alahi@epfl.ch)
|
||||
// and Pierre Vandergheynst (pierre.vandergheynst@epfl.ch)
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <opencv2/core.hpp>
|
||||
#include "opencv2/core/utility.hpp"
|
||||
#include <opencv2/highgui.hpp>
|
||||
#include <opencv2/features2d.hpp>
|
||||
#include <opencv2/nonfree.hpp>
|
||||
|
||||
using namespace cv;
|
||||
|
||||
static void help( char** argv )
|
||||
{
|
||||
std::cout << "\nUsage: " << argv[0] << " [path/to/image1] [path/to/image2] \n"
|
||||
<< "This is an example on how to use the keypoint descriptor presented in the following paper: \n"
|
||||
<< "A. Alahi, R. Ortiz, and P. Vandergheynst. FREAK: Fast Retina Keypoint. \n"
|
||||
<< "In IEEE Conference on Computer Vision and Pattern Recognition, 2012. CVPR 2012 Open Source Award winner \n"
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
int main( int argc, char** argv ) {
|
||||
// check http://docs.opencv.org/doc/tutorials/features2d/table_of_content_features2d/table_of_content_features2d.html
|
||||
// for OpenCV general detection/matching framework details
|
||||
|
||||
if( argc != 3 ) {
|
||||
help(argv);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Load images
|
||||
Mat imgA = imread(argv[1], IMREAD_GRAYSCALE );
|
||||
if( !imgA.data ) {
|
||||
std::cout<< " --(!) Error reading image " << argv[1] << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
Mat imgB = imread(argv[2], IMREAD_GRAYSCALE );
|
||||
if( !imgB.data ) {
|
||||
std::cout << " --(!) Error reading image " << argv[2] << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::vector<KeyPoint> keypointsA, keypointsB;
|
||||
Mat descriptorsA, descriptorsB;
|
||||
std::vector<DMatch> matches;
|
||||
|
||||
// DETECTION
|
||||
// Any openCV detector such as
|
||||
SurfFeatureDetector detector(2000,4);
|
||||
|
||||
// DESCRIPTOR
|
||||
// Our proposed FREAK descriptor
|
||||
// (rotation invariance, scale invariance, pattern radius corresponding to SMALLEST_KP_SIZE,
|
||||
// number of octaves, optional vector containing the selected pairs)
|
||||
// FREAK extractor(true, true, 22, 4, std::vector<int>());
|
||||
FREAK extractor;
|
||||
|
||||
// MATCHER
|
||||
// The standard Hamming distance can be used such as
|
||||
// BFMatcher matcher(NORM_HAMMING);
|
||||
// or the proposed cascade of hamming distance using SSSE3
|
||||
BFMatcher matcher(extractor.defaultNorm());
|
||||
|
||||
// detect
|
||||
double t = (double)getTickCount();
|
||||
detector.detect( imgA, keypointsA );
|
||||
detector.detect( imgB, keypointsB );
|
||||
t = ((double)getTickCount() - t)/getTickFrequency();
|
||||
std::cout << "detection time [s]: " << t/1.0 << std::endl;
|
||||
|
||||
// extract
|
||||
t = (double)getTickCount();
|
||||
extractor.compute( imgA, keypointsA, descriptorsA );
|
||||
extractor.compute( imgB, keypointsB, descriptorsB );
|
||||
t = ((double)getTickCount() - t)/getTickFrequency();
|
||||
std::cout << "extraction time [s]: " << t << std::endl;
|
||||
|
||||
// match
|
||||
t = (double)getTickCount();
|
||||
matcher.match(descriptorsA, descriptorsB, matches);
|
||||
t = ((double)getTickCount() - t)/getTickFrequency();
|
||||
std::cout << "matching time [s]: " << t << std::endl;
|
||||
|
||||
// Draw matches
|
||||
Mat imgMatch;
|
||||
drawMatches(imgA, keypointsA, imgB, keypointsB, matches, imgMatch);
|
||||
|
||||
namedWindow("matches", WINDOW_KEEPRATIO);
|
||||
imshow("matches", imgMatch);
|
||||
waitKey(0);
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
#include "opencv2/imgproc/imgproc.hpp"
|
||||
#include "opencv2/contrib/contrib.hpp"
|
||||
#include "opencv2/highgui/highgui.hpp"
|
||||
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
#include <ctime>
|
||||
|
||||
using namespace cv;
|
||||
using namespace std;
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
if( argc != 2 )
|
||||
{
|
||||
cout << "Colors count should be passed." << endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int colorsCount = atoi(argv[1]);
|
||||
vector<Scalar> colors;
|
||||
theRNG() = (uint64)time(0);
|
||||
generateColors( colors, colorsCount );
|
||||
|
||||
int stripWidth = 20;
|
||||
Mat strips(300, colorsCount*stripWidth, CV_8UC3);
|
||||
for( int i = 0; i < colorsCount; i++ )
|
||||
{
|
||||
strips.colRange(i*stripWidth, (i+1)*stripWidth) = colors[i];
|
||||
}
|
||||
|
||||
imshow( "strips", strips );
|
||||
waitKey();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
#include "opencv2/calib3d/calib3d.hpp"
|
||||
#include "opencv2/features2d/features2d.hpp"
|
||||
#include "opencv2/highgui/highgui.hpp"
|
||||
#include "opencv2/imgproc/imgproc.hpp"
|
||||
#include "opencv2/nonfree/nonfree.hpp"
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
|
||||
static void help()
|
||||
{
|
||||
printf("Use the SURF descriptor for matching keypoints between 2 images\n");
|
||||
printf("Format: \n./generic_descriptor_match <image1> <image2> <algorithm> <XML params>\n");
|
||||
printf("For example: ./generic_descriptor_match ../c/scene_l.bmp ../c/scene_r.bmp FERN fern_params.xml\n");
|
||||
}
|
||||
|
||||
Mat DrawCorrespondences(const Mat& img1, const vector<KeyPoint>& features1, const Mat& img2,
|
||||
const vector<KeyPoint>& features2, const vector<DMatch>& desc_idx);
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
if (argc != 5)
|
||||
{
|
||||
help();
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string img1_name = std::string(argv[1]);
|
||||
std::string img2_name = std::string(argv[2]);
|
||||
std::string alg_name = std::string(argv[3]);
|
||||
std::string params_filename = std::string(argv[4]);
|
||||
|
||||
Ptr<GenericDescriptorMatcher> descriptorMatcher = GenericDescriptorMatcher::create(alg_name, params_filename);
|
||||
if( !descriptorMatcher )
|
||||
{
|
||||
printf ("Cannot create descriptor\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
//printf("Reading the images...\n");
|
||||
Mat img1 = imread(img1_name, IMREAD_GRAYSCALE);
|
||||
Mat img2 = imread(img2_name, IMREAD_GRAYSCALE);
|
||||
|
||||
// extract keypoints from the first image
|
||||
SURF surf_extractor(5.0e3);
|
||||
vector<KeyPoint> keypoints1;
|
||||
|
||||
// printf("Extracting keypoints\n");
|
||||
surf_extractor(img1, Mat(), keypoints1);
|
||||
|
||||
printf("Extracted %d keypoints from the first image\n", (int)keypoints1.size());
|
||||
|
||||
vector<KeyPoint> keypoints2;
|
||||
surf_extractor(img2, Mat(), keypoints2);
|
||||
printf("Extracted %d keypoints from the second image\n", (int)keypoints2.size());
|
||||
|
||||
printf("Finding nearest neighbors... \n");
|
||||
// find NN for each of keypoints2 in keypoints1
|
||||
vector<DMatch> matches2to1;
|
||||
descriptorMatcher->match( img2, keypoints2, img1, keypoints1, matches2to1 );
|
||||
printf("Done\n");
|
||||
|
||||
Mat img_corr = DrawCorrespondences(img1, keypoints1, img2, keypoints2, matches2to1);
|
||||
|
||||
imshow("correspondences", img_corr);
|
||||
waitKey(0);
|
||||
}
|
||||
|
||||
Mat DrawCorrespondences(const Mat& img1, const vector<KeyPoint>& features1, const Mat& img2,
|
||||
const vector<KeyPoint>& features2, const vector<DMatch>& desc_idx)
|
||||
{
|
||||
Mat part, img_corr(Size(img1.cols + img2.cols, MAX(img1.rows, img2.rows)), CV_8UC3);
|
||||
img_corr = Scalar::all(0);
|
||||
part = img_corr(Rect(0, 0, img1.cols, img1.rows));
|
||||
cvtColor(img1, part, COLOR_GRAY2RGB);
|
||||
part = img_corr(Rect(img1.cols, 0, img2.cols, img2.rows));
|
||||
cvtColor(img1, part, COLOR_GRAY2RGB);
|
||||
|
||||
for (size_t i = 0; i < features1.size(); i++)
|
||||
{
|
||||
circle(img_corr, features1[i].pt, 3, Scalar(0, 0, 255));
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < features2.size(); i++)
|
||||
{
|
||||
Point pt(cvRound(features2[i].pt.x + img1.cols), cvRound(features2[i].pt.y));
|
||||
circle(img_corr, pt, 3, Scalar(0, 0, 255));
|
||||
line(img_corr, features1[desc_idx[i].trainIdx].pt, pt, Scalar(0, 255, 0));
|
||||
}
|
||||
|
||||
return img_corr;
|
||||
}
|
||||
@@ -1,182 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* Hybrid Tracking in OpenCV
|
||||
* Usage: ./hybridtrackingsample live
|
||||
*
|
||||
* For Benchmarking against the Bonn benchmark dataset
|
||||
* wget http://www.iai.uni-bonn.de/~kleind/tracking/datasets/seqG.zip
|
||||
* unzip seqG.zip -d ./seqG
|
||||
* ffmpeg -i seqG/Vid_G_rubikscube.avi seqG/%04d.png
|
||||
* ./hytrack seqG/Vid_G_rubikscube.txt
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <iostream>
|
||||
|
||||
#include "opencv2/highgui/highgui.hpp"
|
||||
#include "opencv2/contrib/hybridtracker.hpp"
|
||||
|
||||
#ifndef _CRT_SECURE_NO_WARNINGS
|
||||
# define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
|
||||
using namespace cv;
|
||||
using namespace std;
|
||||
|
||||
Mat frame, image;
|
||||
Rect selection;
|
||||
Point origin;
|
||||
bool selectObject = false;
|
||||
int trackObject = 0;
|
||||
int live = 1;
|
||||
|
||||
static void drawRectangle(Mat* img, Rect win) {
|
||||
rectangle(*img, Point(win.x, win.y), Point(win.x + win.width, win.y
|
||||
+ win.height), Scalar(0, 255, 0), 2, CV_AA);
|
||||
}
|
||||
|
||||
static void onMouse(int event, int x, int y, int, void*) {
|
||||
if (selectObject) {
|
||||
selection.x = MIN(x, origin.x);
|
||||
selection.y = MIN(y, origin.y);
|
||||
selection.width = std::abs(x - origin.x);
|
||||
selection.height = std::abs(y - origin.y);
|
||||
selection &= Rect(0, 0, image.cols, image.rows);
|
||||
}
|
||||
|
||||
switch (event) {
|
||||
case EVENT_LBUTTONDOWN:
|
||||
origin = Point(x, y);
|
||||
selection = Rect(x, y, 0, 0);
|
||||
selectObject = true;
|
||||
break;
|
||||
case EVENT_LBUTTONUP:
|
||||
selectObject = false;
|
||||
trackObject = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void help()
|
||||
{
|
||||
printf("Usage: ./hytrack live or ./hytrack <test_file> \n\
|
||||
For Live View or Benchmarking. Read documentation is source code.\n\n");
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
if(argc != 2) {
|
||||
help();
|
||||
return 1;
|
||||
}
|
||||
|
||||
FILE* f = 0;
|
||||
VideoCapture cap;
|
||||
char test_file[20] = "";
|
||||
|
||||
if (strcmp(argv[1], "live") != 0)
|
||||
{
|
||||
sprintf(test_file, "%s", argv[1]);
|
||||
f = fopen(test_file, "r");
|
||||
char vid[20];
|
||||
int values_read = fscanf(f, "%s\n", vid);
|
||||
CV_Assert(values_read == 1);
|
||||
cout << "Benchmarking against " << vid << endl;
|
||||
live = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
cap.open(0);
|
||||
if (!cap.isOpened())
|
||||
{
|
||||
cout << "Failed to open camera" << endl;
|
||||
return 0;
|
||||
}
|
||||
cout << "Opened camera" << endl;
|
||||
cap.set(CAP_PROP_FRAME_WIDTH, 640);
|
||||
cap.set(CAP_PROP_FRAME_HEIGHT, 480);
|
||||
cap >> frame;
|
||||
}
|
||||
|
||||
HybridTrackerParams params;
|
||||
// motion model params
|
||||
params.motion_model = CvMotionModel::LOW_PASS_FILTER;
|
||||
params.low_pass_gain = 0.1f;
|
||||
// mean shift params
|
||||
params.ms_tracker_weight = 0.8f;
|
||||
params.ms_params.tracking_type = CvMeanShiftTrackerParams::HS;
|
||||
// feature tracking params
|
||||
params.ft_tracker_weight = 0.2f;
|
||||
params.ft_params.feature_type = CvFeatureTrackerParams::OPTICAL_FLOW;
|
||||
params.ft_params.window_size = 0;
|
||||
|
||||
HybridTracker tracker(params);
|
||||
char img_file[20] = "seqG/0001.png";
|
||||
char img_file_num[10];
|
||||
namedWindow("Win", 1);
|
||||
|
||||
setMouseCallback("Win", onMouse, 0);
|
||||
|
||||
int i = 0;
|
||||
float w[4];
|
||||
for(;;)
|
||||
{
|
||||
i++;
|
||||
if (live)
|
||||
{
|
||||
cap >> frame;
|
||||
if( frame.empty() )
|
||||
break;
|
||||
frame.copyTo(image);
|
||||
}
|
||||
else
|
||||
{
|
||||
int values_read = fscanf(f, "%d %f %f %f %f\n", &i, &w[0], &w[1], &w[2], &w[3]);
|
||||
CV_Assert(values_read == 5);
|
||||
sprintf(img_file, "seqG/%04d.png", i);
|
||||
image = imread(img_file, IMREAD_COLOR);
|
||||
if (image.empty())
|
||||
break;
|
||||
selection = Rect(cvRound(w[0]*image.cols), cvRound(w[1]*image.rows),
|
||||
cvRound(w[2]*image.cols), cvRound(w[3]*image.rows));
|
||||
}
|
||||
|
||||
sprintf(img_file_num, "Frame: %d", i);
|
||||
putText(image, img_file_num, Point(10, image.rows-20), FONT_HERSHEY_PLAIN, 0.75, Scalar(255, 255, 255));
|
||||
if (!image.empty())
|
||||
{
|
||||
|
||||
if (trackObject < 0)
|
||||
{
|
||||
tracker.newTracker(image, selection);
|
||||
trackObject = 1;
|
||||
}
|
||||
|
||||
if (trackObject)
|
||||
{
|
||||
tracker.updateTracker(image);
|
||||
drawRectangle(&image, tracker.getTrackingWindow());
|
||||
}
|
||||
|
||||
if (selectObject && selection.width > 0 && selection.height > 0)
|
||||
{
|
||||
Mat roi(image, selection);
|
||||
bitwise_not(roi, roi);
|
||||
}
|
||||
|
||||
drawRectangle(&image, Rect(cvRound(w[0]*image.cols), cvRound(w[1]*image.rows),
|
||||
cvRound(w[2]*image.cols), cvRound(w[3]*image.rows)));
|
||||
imshow("Win", image);
|
||||
|
||||
waitKey(100);
|
||||
}
|
||||
else
|
||||
i = 0;
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
@@ -2,12 +2,10 @@
|
||||
#include <iostream>
|
||||
#include <opencv2/imgproc/imgproc.hpp>
|
||||
#include <opencv2/highgui/highgui.hpp>
|
||||
#include <opencv2/flann/miniflann.hpp>
|
||||
#include <opencv2/core/utility.hpp>
|
||||
|
||||
using namespace cv; // all the new API is put into "cv" namespace. Export its content
|
||||
using namespace std;
|
||||
using namespace cv::flann;
|
||||
|
||||
static void help()
|
||||
{
|
||||
|
||||
@@ -1,165 +0,0 @@
|
||||
#include <iostream>
|
||||
#include "opencv2/objdetect/objdetect.hpp"
|
||||
#include "opencv2/highgui/highgui.hpp"
|
||||
#include "opencv2/contrib/contrib.hpp"
|
||||
|
||||
#if defined(WIN32) || defined(_WIN32)
|
||||
#include <io.h>
|
||||
#else
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
|
||||
static void help()
|
||||
{
|
||||
cout << "This program demonstrated the use of the latentSVM detector." << endl <<
|
||||
"It reads in a trained object models and then uses them to detect the objects in an images." << endl <<
|
||||
endl <<
|
||||
"Call:" << endl <<
|
||||
"./latentsvm_multidetect <imagesFolder> <modelsFolder> [<overlapThreshold>][<threadsNumber>]" << endl <<
|
||||
"<overlapThreshold> - threshold for the non-maximum suppression algorithm." << endl <<
|
||||
"Example of <modelsFolder> is opencv_extra/testdata/cv/latentsvmdetector/models_VOC2007" << endl <<
|
||||
endl <<
|
||||
"Keys:" << endl <<
|
||||
"'n' - to go to the next image;" << endl <<
|
||||
"'esc' - to quit." << endl <<
|
||||
endl;
|
||||
}
|
||||
|
||||
static void detectAndDrawObjects( Mat& image, LatentSvmDetector& detector, const vector<Scalar>& colors, float overlapThreshold, int numThreads )
|
||||
{
|
||||
vector<LatentSvmDetector::ObjectDetection> detections;
|
||||
|
||||
TickMeter tm;
|
||||
tm.start();
|
||||
detector.detect( image, detections, overlapThreshold, numThreads);
|
||||
tm.stop();
|
||||
|
||||
cout << "Detection time = " << tm.getTimeSec() << " sec" << endl;
|
||||
|
||||
const vector<String> classNames = detector.getClassNames();
|
||||
CV_Assert( colors.size() == classNames.size() );
|
||||
|
||||
for( size_t i = 0; i < detections.size(); i++ )
|
||||
{
|
||||
const LatentSvmDetector::ObjectDetection& od = detections[i];
|
||||
rectangle( image, od.rect, colors[od.classID], 3 );
|
||||
}
|
||||
// put text over the all rectangles
|
||||
for( size_t i = 0; i < detections.size(); i++ )
|
||||
{
|
||||
const LatentSvmDetector::ObjectDetection& od = detections[i];
|
||||
putText( image, classNames[od.classID], Point(od.rect.x+4,od.rect.y+13), FONT_HERSHEY_SIMPLEX, 0.55, colors[od.classID], 2 );
|
||||
}
|
||||
}
|
||||
|
||||
static void readDirectory( const string& directoryName, vector<String>& filenames, bool addDirectoryName=true )
|
||||
{
|
||||
filenames.clear();
|
||||
|
||||
#if defined(WIN32) | defined(_WIN32)
|
||||
struct _finddata_t s_file;
|
||||
string str = directoryName + "\\*.*";
|
||||
|
||||
intptr_t h_file = _findfirst( str.c_str(), &s_file );
|
||||
if( h_file != static_cast<intptr_t>(-1.0) )
|
||||
{
|
||||
do
|
||||
{
|
||||
if( addDirectoryName )
|
||||
filenames.push_back(directoryName + "\\" + s_file.name);
|
||||
else
|
||||
filenames.push_back((string)s_file.name);
|
||||
}
|
||||
while( _findnext( h_file, &s_file ) == 0 );
|
||||
}
|
||||
_findclose( h_file );
|
||||
#else
|
||||
DIR* dir = opendir( directoryName.c_str() );
|
||||
if( dir != NULL )
|
||||
{
|
||||
struct dirent* dent;
|
||||
while( (dent = readdir(dir)) != NULL )
|
||||
{
|
||||
if( addDirectoryName )
|
||||
filenames.push_back( directoryName + "/" + string(dent->d_name) );
|
||||
else
|
||||
filenames.push_back( string(dent->d_name) );
|
||||
}
|
||||
|
||||
closedir( dir );
|
||||
}
|
||||
#endif
|
||||
|
||||
sort( filenames.begin(), filenames.end() );
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
help();
|
||||
|
||||
string images_folder, models_folder;
|
||||
float overlapThreshold = 0.2f;
|
||||
int numThreads = -1;
|
||||
if( argc > 2 )
|
||||
{
|
||||
images_folder = argv[1];
|
||||
models_folder = argv[2];
|
||||
if( argc > 3 ) overlapThreshold = (float)atof(argv[3]);
|
||||
if( overlapThreshold < 0 || overlapThreshold > 1)
|
||||
{
|
||||
cout << "overlapThreshold must be in interval (0,1)." << endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if( argc > 4 ) numThreads = atoi(argv[4]);
|
||||
}
|
||||
|
||||
vector<String> images_filenames, models_filenames;
|
||||
readDirectory( images_folder, images_filenames );
|
||||
readDirectory( models_folder, models_filenames );
|
||||
|
||||
LatentSvmDetector detector( models_filenames );
|
||||
if( detector.empty() )
|
||||
{
|
||||
cout << "Models cann't be loaded" << endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
const vector<String>& classNames = detector.getClassNames();
|
||||
cout << "Loaded " << classNames.size() << " models:" << endl;
|
||||
for( size_t i = 0; i < classNames.size(); i++ )
|
||||
{
|
||||
cout << i << ") " << classNames[i] << "; ";
|
||||
}
|
||||
cout << endl;
|
||||
|
||||
cout << "overlapThreshold = " << overlapThreshold << endl;
|
||||
|
||||
vector<Scalar> colors;
|
||||
generateColors( colors, detector.getClassNames().size() );
|
||||
|
||||
for( size_t i = 0; i < images_filenames.size(); i++ )
|
||||
{
|
||||
Mat image = imread( images_filenames[i] );
|
||||
if( image.empty() ) continue;
|
||||
|
||||
cout << "Process image " << images_filenames[i] << endl;
|
||||
detectAndDrawObjects( image, detector, colors, overlapThreshold, numThreads );
|
||||
|
||||
imshow( "result", image );
|
||||
|
||||
for(;;)
|
||||
{
|
||||
int c = waitKey();
|
||||
if( (char)c == 'n')
|
||||
break;
|
||||
else if( (char)c == '\x1b' )
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
/*Authors
|
||||
* Manuela Chessa, Fabio Solari, Fabio Tatti, Silvio P. Sabatini
|
||||
*
|
||||
* manuela.chessa@unige.it, fabio.solari@unige.it
|
||||
*
|
||||
* PSPC-lab - University of Genoa
|
||||
*/
|
||||
|
||||
#include "opencv2/contrib.hpp"
|
||||
#include "opencv2/highgui.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
|
||||
using namespace cv;
|
||||
using namespace std;
|
||||
|
||||
static void help()
|
||||
{
|
||||
cout << "LogPolar Blind Spot Model sample.\nShortcuts:"
|
||||
"\n\tn for nearest pixel technique"
|
||||
"\n\tb for bilinear interpolation technique"
|
||||
"\n\to for overlapping circular receptive fields"
|
||||
"\n\ta for adjacent receptive fields"
|
||||
"\n\tq or ESC quit\n";
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
Mat img = imread(argc > 1 ? argv[1] : "lena.jpg",1); // open the image
|
||||
if(img.empty()) // check if we succeeded
|
||||
{
|
||||
cout << "can not load image\n";
|
||||
return 0;
|
||||
}
|
||||
help();
|
||||
|
||||
Size s=img.size();
|
||||
int w=s.width, h=s.height;
|
||||
int ro0=3; //radius of the blind spot
|
||||
int R=120; //number of rings
|
||||
|
||||
//Creation of the four different objects that implement the four log-polar transformations
|
||||
//Off-line computation
|
||||
Point2i center(w/2,h/2);
|
||||
LogPolar_Interp nearest(w, h, center, R, ro0, INTER_NEAREST);
|
||||
LogPolar_Interp bilin(w,h, center,R,ro0);
|
||||
LogPolar_Overlapping overlap(w,h,center,R,ro0);
|
||||
LogPolar_Adjacent adj(w,h,center,R,ro0,0.25);
|
||||
|
||||
namedWindow("Cartesian",1);
|
||||
namedWindow("retinal",1);
|
||||
namedWindow("cortical",1);
|
||||
int wk='n';
|
||||
Mat Cortical, Retinal;
|
||||
|
||||
//On-line computation
|
||||
for(;;)
|
||||
{
|
||||
if(wk=='n'){
|
||||
Cortical=nearest.to_cortical(img);
|
||||
Retinal=nearest.to_cartesian(Cortical);
|
||||
}else if (wk=='b'){
|
||||
Cortical=bilin.to_cortical(img);
|
||||
Retinal=bilin.to_cartesian(Cortical);
|
||||
}else if (wk=='o'){
|
||||
Cortical=overlap.to_cortical(img);
|
||||
Retinal=overlap.to_cartesian(Cortical);
|
||||
}else if (wk=='a'){
|
||||
Cortical=adj.to_cortical(img);
|
||||
Retinal=adj.to_cartesian(Cortical);
|
||||
}
|
||||
|
||||
imshow("Cartesian", img);
|
||||
imshow("cortical", Cortical);
|
||||
imshow("retinal", Retinal);
|
||||
|
||||
int c=waitKey(15);
|
||||
if (c>0) wk=c;
|
||||
if(wk =='q' || (wk & 255) == 27) break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include "opencv2/core/core.hpp"
|
||||
#include "opencv2/features2d/features2d.hpp"
|
||||
#include "opencv2/highgui/highgui.hpp"
|
||||
#include "opencv2/nonfree/nonfree.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
|
||||
static void help()
|
||||
{
|
||||
printf("\nThis program demonstrates using features2d detector, descriptor extractor and simple matcher\n"
|
||||
"Using the SURF desriptor:\n"
|
||||
"\n"
|
||||
"Usage:\n matcher_simple <image1> <image2>\n");
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
if(argc != 3)
|
||||
{
|
||||
help();
|
||||
return -1;
|
||||
}
|
||||
|
||||
Mat img1 = imread(argv[1], IMREAD_GRAYSCALE);
|
||||
Mat img2 = imread(argv[2], IMREAD_GRAYSCALE);
|
||||
if(img1.empty() || img2.empty())
|
||||
{
|
||||
printf("Can't read one of the images\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// detecting keypoints
|
||||
SurfFeatureDetector detector(400);
|
||||
vector<KeyPoint> keypoints1, keypoints2;
|
||||
detector.detect(img1, keypoints1);
|
||||
detector.detect(img2, keypoints2);
|
||||
|
||||
// computing descriptors
|
||||
SurfDescriptorExtractor extractor;
|
||||
Mat descriptors1, descriptors2;
|
||||
extractor.compute(img1, keypoints1, descriptors1);
|
||||
extractor.compute(img2, keypoints2, descriptors2);
|
||||
|
||||
// matching descriptors
|
||||
BFMatcher matcher(extractor.defaultNorm());
|
||||
vector<DMatch> matches;
|
||||
matcher.match(descriptors1, descriptors2, matches);
|
||||
|
||||
// drawing the results
|
||||
namedWindow("matches", 1);
|
||||
Mat img_matches;
|
||||
drawMatches(img1, keypoints1, img2, keypoints2, matches, img_matches);
|
||||
imshow("matches", img_matches);
|
||||
waitKey(0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,262 +0,0 @@
|
||||
#include "opencv2/highgui/highgui.hpp"
|
||||
#include "opencv2/features2d/features2d.hpp"
|
||||
#include "opencv2/contrib/contrib.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
using namespace cv;
|
||||
using namespace std;
|
||||
|
||||
const string defaultDetectorType = "SURF";
|
||||
const string defaultDescriptorType = "SURF";
|
||||
const string defaultMatcherType = "FlannBased";
|
||||
const string defaultQueryImageName = "../../opencv/samples/cpp/matching_to_many_images/query.png";
|
||||
const string defaultFileWithTrainImages = "../../opencv/samples/cpp/matching_to_many_images/train/trainImages.txt";
|
||||
const string defaultDirToSaveResImages = "../../opencv/samples/cpp/matching_to_many_images/results";
|
||||
|
||||
static void printPrompt( const string& applName )
|
||||
{
|
||||
cout << "/*\n"
|
||||
<< " * This is a sample on matching descriptors detected on one image to descriptors detected in image set.\n"
|
||||
<< " * So we have one query image and several train images. For each keypoint descriptor of query image\n"
|
||||
<< " * the one nearest train descriptor is found the entire collection of train images. To visualize the result\n"
|
||||
<< " * of matching we save images, each of which combines query and train image with matches between them (if they exist).\n"
|
||||
<< " * Match is drawn as line between corresponding points. Count of all matches is equel to count of\n"
|
||||
<< " * query keypoints, so we have the same count of lines in all set of result images (but not for each result\n"
|
||||
<< " * (train) image).\n"
|
||||
<< " */\n" << endl;
|
||||
|
||||
cout << endl << "Format:\n" << endl;
|
||||
cout << "./" << applName << " [detectorType] [descriptorType] [matcherType] [queryImage] [fileWithTrainImages] [dirToSaveResImages]" << endl;
|
||||
cout << endl;
|
||||
|
||||
cout << "\nExample:" << endl
|
||||
<< "./" << applName << " " << defaultDetectorType << " " << defaultDescriptorType << " " << defaultMatcherType << " "
|
||||
<< defaultQueryImageName << " " << defaultFileWithTrainImages << " " << defaultDirToSaveResImages << endl;
|
||||
}
|
||||
|
||||
static void maskMatchesByTrainImgIdx( const vector<DMatch>& matches, int trainImgIdx, vector<char>& mask )
|
||||
{
|
||||
mask.resize( matches.size() );
|
||||
fill( mask.begin(), mask.end(), 0 );
|
||||
for( size_t i = 0; i < matches.size(); i++ )
|
||||
{
|
||||
if( matches[i].imgIdx == trainImgIdx )
|
||||
mask[i] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void readTrainFilenames( const string& filename, string& dirName, vector<string>& trainFilenames )
|
||||
{
|
||||
trainFilenames.clear();
|
||||
|
||||
ifstream file( filename.c_str() );
|
||||
if ( !file.is_open() )
|
||||
return;
|
||||
|
||||
size_t pos = filename.rfind('\\');
|
||||
char dlmtr = '\\';
|
||||
if (pos == string::npos)
|
||||
{
|
||||
pos = filename.rfind('/');
|
||||
dlmtr = '/';
|
||||
}
|
||||
dirName = pos == string::npos ? "" : filename.substr(0, pos) + dlmtr;
|
||||
|
||||
while( !file.eof() )
|
||||
{
|
||||
string str; getline( file, str );
|
||||
if( str.empty() ) break;
|
||||
trainFilenames.push_back(str);
|
||||
}
|
||||
file.close();
|
||||
}
|
||||
|
||||
static bool createDetectorDescriptorMatcher( const string& detectorType, const string& descriptorType, const string& matcherType,
|
||||
Ptr<FeatureDetector>& featureDetector,
|
||||
Ptr<DescriptorExtractor>& descriptorExtractor,
|
||||
Ptr<DescriptorMatcher>& descriptorMatcher )
|
||||
{
|
||||
cout << "< Creating feature detector, descriptor extractor and descriptor matcher ..." << endl;
|
||||
featureDetector = FeatureDetector::create( detectorType );
|
||||
descriptorExtractor = DescriptorExtractor::create( descriptorType );
|
||||
descriptorMatcher = DescriptorMatcher::create( matcherType );
|
||||
cout << ">" << endl;
|
||||
|
||||
bool isCreated = featureDetector && descriptorExtractor && descriptorMatcher;
|
||||
if( !isCreated )
|
||||
cout << "Can not create feature detector or descriptor extractor or descriptor matcher of given types." << endl << ">" << endl;
|
||||
|
||||
return isCreated;
|
||||
}
|
||||
|
||||
static bool readImages( const string& queryImageName, const string& trainFilename,
|
||||
Mat& queryImage, vector <Mat>& trainImages, vector<string>& trainImageNames )
|
||||
{
|
||||
cout << "< Reading the images..." << endl;
|
||||
queryImage = imread( queryImageName, IMREAD_GRAYSCALE);
|
||||
if( queryImage.empty() )
|
||||
{
|
||||
cout << "Query image can not be read." << endl << ">" << endl;
|
||||
return false;
|
||||
}
|
||||
string trainDirName;
|
||||
readTrainFilenames( trainFilename, trainDirName, trainImageNames );
|
||||
if( trainImageNames.empty() )
|
||||
{
|
||||
cout << "Train image filenames can not be read." << endl << ">" << endl;
|
||||
return false;
|
||||
}
|
||||
int readImageCount = 0;
|
||||
for( size_t i = 0; i < trainImageNames.size(); i++ )
|
||||
{
|
||||
string filename = trainDirName + trainImageNames[i];
|
||||
Mat img = imread( filename, IMREAD_GRAYSCALE );
|
||||
if( img.empty() )
|
||||
cout << "Train image " << filename << " can not be read." << endl;
|
||||
else
|
||||
readImageCount++;
|
||||
trainImages.push_back( img );
|
||||
}
|
||||
if( !readImageCount )
|
||||
{
|
||||
cout << "All train images can not be read." << endl << ">" << endl;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
cout << readImageCount << " train images were read." << endl;
|
||||
cout << ">" << endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void detectKeypoints( const Mat& queryImage, vector<KeyPoint>& queryKeypoints,
|
||||
const vector<Mat>& trainImages, vector<vector<KeyPoint> >& trainKeypoints,
|
||||
Ptr<FeatureDetector>& featureDetector )
|
||||
{
|
||||
cout << endl << "< Extracting keypoints from images..." << endl;
|
||||
featureDetector->detect( queryImage, queryKeypoints );
|
||||
featureDetector->detect( trainImages, trainKeypoints );
|
||||
cout << ">" << endl;
|
||||
}
|
||||
|
||||
static void computeDescriptors( const Mat& queryImage, vector<KeyPoint>& queryKeypoints, Mat& queryDescriptors,
|
||||
const vector<Mat>& trainImages, vector<vector<KeyPoint> >& trainKeypoints, vector<Mat>& trainDescriptors,
|
||||
Ptr<DescriptorExtractor>& descriptorExtractor )
|
||||
{
|
||||
cout << "< Computing descriptors for keypoints..." << endl;
|
||||
descriptorExtractor->compute( queryImage, queryKeypoints, queryDescriptors );
|
||||
descriptorExtractor->compute( trainImages, trainKeypoints, trainDescriptors );
|
||||
|
||||
int totalTrainDesc = 0;
|
||||
for( vector<Mat>::const_iterator tdIter = trainDescriptors.begin(); tdIter != trainDescriptors.end(); tdIter++ )
|
||||
totalTrainDesc += tdIter->rows;
|
||||
|
||||
cout << "Query descriptors count: " << queryDescriptors.rows << "; Total train descriptors count: " << totalTrainDesc << endl;
|
||||
cout << ">" << endl;
|
||||
}
|
||||
|
||||
static void matchDescriptors( const Mat& queryDescriptors, const vector<Mat>& trainDescriptors,
|
||||
vector<DMatch>& matches, Ptr<DescriptorMatcher>& descriptorMatcher )
|
||||
{
|
||||
cout << "< Set train descriptors collection in the matcher and match query descriptors to them..." << endl;
|
||||
TickMeter tm;
|
||||
|
||||
tm.start();
|
||||
descriptorMatcher->add( trainDescriptors );
|
||||
descriptorMatcher->train();
|
||||
tm.stop();
|
||||
double buildTime = tm.getTimeMilli();
|
||||
|
||||
tm.start();
|
||||
descriptorMatcher->match( queryDescriptors, matches );
|
||||
tm.stop();
|
||||
double matchTime = tm.getTimeMilli();
|
||||
|
||||
CV_Assert( queryDescriptors.rows == (int)matches.size() || matches.empty() );
|
||||
|
||||
cout << "Number of matches: " << matches.size() << endl;
|
||||
cout << "Build time: " << buildTime << " ms; Match time: " << matchTime << " ms" << endl;
|
||||
cout << ">" << endl;
|
||||
}
|
||||
|
||||
static void saveResultImages( const Mat& queryImage, const vector<KeyPoint>& queryKeypoints,
|
||||
const vector<Mat>& trainImages, const vector<vector<KeyPoint> >& trainKeypoints,
|
||||
const vector<DMatch>& matches, const vector<string>& trainImagesNames, const string& resultDir )
|
||||
{
|
||||
cout << "< Save results..." << endl;
|
||||
Mat drawImg;
|
||||
vector<char> mask;
|
||||
for( size_t i = 0; i < trainImages.size(); i++ )
|
||||
{
|
||||
if( !trainImages[i].empty() )
|
||||
{
|
||||
maskMatchesByTrainImgIdx( matches, (int)i, mask );
|
||||
drawMatches( queryImage, queryKeypoints, trainImages[i], trainKeypoints[i],
|
||||
matches, drawImg, Scalar(255, 0, 0), Scalar(0, 255, 255), mask );
|
||||
string filename = resultDir + "/res_" + trainImagesNames[i];
|
||||
if( !imwrite( filename, drawImg ) )
|
||||
cout << "Image " << filename << " can not be saved (may be because directory " << resultDir << " does not exist)." << endl;
|
||||
}
|
||||
}
|
||||
cout << ">" << endl;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
string detectorType = defaultDetectorType;
|
||||
string descriptorType = defaultDescriptorType;
|
||||
string matcherType = defaultMatcherType;
|
||||
string queryImageName = defaultQueryImageName;
|
||||
string fileWithTrainImages = defaultFileWithTrainImages;
|
||||
string dirToSaveResImages = defaultDirToSaveResImages;
|
||||
|
||||
if( argc != 7 && argc != 1 )
|
||||
{
|
||||
printPrompt( argv[0] );
|
||||
return -1;
|
||||
}
|
||||
|
||||
if( argc != 1 )
|
||||
{
|
||||
detectorType = argv[1]; descriptorType = argv[2]; matcherType = argv[3];
|
||||
queryImageName = argv[4]; fileWithTrainImages = argv[5];
|
||||
dirToSaveResImages = argv[6];
|
||||
}
|
||||
|
||||
Ptr<FeatureDetector> featureDetector;
|
||||
Ptr<DescriptorExtractor> descriptorExtractor;
|
||||
Ptr<DescriptorMatcher> descriptorMatcher;
|
||||
if( !createDetectorDescriptorMatcher( detectorType, descriptorType, matcherType, featureDetector, descriptorExtractor, descriptorMatcher ) )
|
||||
{
|
||||
printPrompt( argv[0] );
|
||||
return -1;
|
||||
}
|
||||
|
||||
Mat queryImage;
|
||||
vector<Mat> trainImages;
|
||||
vector<string> trainImagesNames;
|
||||
if( !readImages( queryImageName, fileWithTrainImages, queryImage, trainImages, trainImagesNames ) )
|
||||
{
|
||||
printPrompt( argv[0] );
|
||||
return -1;
|
||||
}
|
||||
|
||||
vector<KeyPoint> queryKeypoints;
|
||||
vector<vector<KeyPoint> > trainKeypoints;
|
||||
detectKeypoints( queryImage, queryKeypoints, trainImages, trainKeypoints, featureDetector );
|
||||
|
||||
Mat queryDescriptors;
|
||||
vector<Mat> trainDescriptors;
|
||||
computeDescriptors( queryImage, queryKeypoints, queryDescriptors,
|
||||
trainImages, trainKeypoints, trainDescriptors,
|
||||
descriptorExtractor );
|
||||
|
||||
vector<DMatch> matches;
|
||||
matchDescriptors( queryDescriptors, trainDescriptors, matches, descriptorMatcher );
|
||||
|
||||
saveResultImages( queryImage, queryKeypoints, trainImages, trainKeypoints,
|
||||
matches, trainImagesNames, dirToSaveResImages );
|
||||
return 0;
|
||||
}
|
||||
|
Before Width: | Height: | Size: 119 KiB |
|
Before Width: | Height: | Size: 116 KiB |
|
Before Width: | Height: | Size: 112 KiB |
|
Before Width: | Height: | Size: 118 KiB |
@@ -1,3 +0,0 @@
|
||||
1.png
|
||||
2.png
|
||||
3.png
|
||||
@@ -1,77 +0,0 @@
|
||||
#include "opencv2/highgui/highgui.hpp"
|
||||
#include "opencv2/core/core.hpp"
|
||||
#include "opencv2/imgproc/imgproc.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace cv;
|
||||
using namespace std;
|
||||
|
||||
static void help(char** argv)
|
||||
{
|
||||
cout << "\nDemonstrate mean-shift based color segmentation in spatial pyramid.\n"
|
||||
<< "Call:\n " << argv[0] << " image\n"
|
||||
<< "This program allows you to set the spatial and color radius\n"
|
||||
<< "of the mean shift window as well as the number of pyramid reduction levels explored\n"
|
||||
<< endl;
|
||||
}
|
||||
|
||||
//This colors the segmentations
|
||||
static void floodFillPostprocess( Mat& img, const Scalar& colorDiff=Scalar::all(1) )
|
||||
{
|
||||
CV_Assert( !img.empty() );
|
||||
RNG rng = theRNG();
|
||||
Mat mask( img.rows+2, img.cols+2, CV_8UC1, Scalar::all(0) );
|
||||
for( int y = 0; y < img.rows; y++ )
|
||||
{
|
||||
for( int x = 0; x < img.cols; x++ )
|
||||
{
|
||||
if( mask.at<uchar>(y+1, x+1) == 0 )
|
||||
{
|
||||
Scalar newVal( rng(256), rng(256), rng(256) );
|
||||
floodFill( img, mask, Point(x,y), newVal, 0, colorDiff, colorDiff );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string winName = "meanshift";
|
||||
int spatialRad, colorRad, maxPyrLevel;
|
||||
Mat img, res;
|
||||
|
||||
static void meanShiftSegmentation( int, void* )
|
||||
{
|
||||
cout << "spatialRad=" << spatialRad << "; "
|
||||
<< "colorRad=" << colorRad << "; "
|
||||
<< "maxPyrLevel=" << maxPyrLevel << endl;
|
||||
pyrMeanShiftFiltering( img, res, spatialRad, colorRad, maxPyrLevel );
|
||||
floodFillPostprocess( res, Scalar::all(2) );
|
||||
imshow( winName, res );
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
if( argc !=2 )
|
||||
{
|
||||
help(argv);
|
||||
return -1;
|
||||
}
|
||||
|
||||
img = imread( argv[1] );
|
||||
if( img.empty() )
|
||||
return -1;
|
||||
|
||||
spatialRad = 10;
|
||||
colorRad = 10;
|
||||
maxPyrLevel = 1;
|
||||
|
||||
namedWindow( winName, WINDOW_AUTOSIZE );
|
||||
|
||||
createTrackbar( "spatialRad", winName, &spatialRad, 80, meanShiftSegmentation );
|
||||
createTrackbar( "colorRad", winName, &colorRad, 60, meanShiftSegmentation );
|
||||
createTrackbar( "maxPyrLevel", winName, &maxPyrLevel, 5, meanShiftSegmentation );
|
||||
|
||||
meanShiftSegmentation(0, 0);
|
||||
waitKey();
|
||||
return 0;
|
||||
}
|
||||
@@ -1,180 +0,0 @@
|
||||
#include <opencv2/core/utility.hpp>
|
||||
#include <opencv2/imgproc.hpp>
|
||||
#include <opencv2/objdetect.hpp>
|
||||
#include <opencv2/highgui.hpp>
|
||||
#include <opencv2/softcascade.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
|
||||
void filter_rects(const std::vector<cv::Rect>& candidates, std::vector<cv::Rect>& objects);
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
const std::string keys =
|
||||
"{help h usage ? | | print this message and exit }"
|
||||
"{cascade c | | path to cascade xml, if empty HOG detector will be executed }"
|
||||
"{frame f | | wildchart pattern to frame source}"
|
||||
"{min_scale |0.4 | minimum scale to detect }"
|
||||
"{max_scale |5.0 | maxamum scale to detect }"
|
||||
"{total_scales |55 | prefered number of scales between min and max }"
|
||||
"{write_file wf |0 | write to .txt. Disabled by default.}"
|
||||
"{write_image wi |0 | write to image. Disabled by default.}"
|
||||
"{show_image si |1 | show image. Enabled by default.}"
|
||||
"{threshold thr |-1 | detection threshold. Detections with score less then threshold will be ignored.}"
|
||||
;
|
||||
|
||||
cv::CommandLineParser parser(argc, argv, keys);
|
||||
parser.about("Soft cascade training application.");
|
||||
|
||||
if (parser.has("help"))
|
||||
{
|
||||
parser.printMessage();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!parser.check())
|
||||
{
|
||||
parser.printErrors();
|
||||
return 1;
|
||||
}
|
||||
|
||||
int wf = parser.get<int>("write_file");
|
||||
if (wf) std::cout << "resulte will be stored to .txt file with the same name as image." << std::endl;
|
||||
|
||||
int wi = parser.get<int>("write_image");
|
||||
if (wi) std::cout << "resulte will be stored to image with the same name as input plus dt." << std::endl;
|
||||
|
||||
int si = parser.get<int>("show_image");
|
||||
|
||||
float minScale = parser.get<float>("min_scale");
|
||||
float maxScale = parser.get<float>("max_scale");
|
||||
int scales = parser.get<int>("total_scales");
|
||||
int thr = parser.get<int>("threshold");
|
||||
|
||||
cv::HOGDescriptor hog;
|
||||
cv::softcascade::Detector cascade;
|
||||
|
||||
bool useHOG = false;
|
||||
std::string cascadePath = parser.get<std::string>("cascade");
|
||||
if (cascadePath.empty())
|
||||
{
|
||||
useHOG = true;
|
||||
hog.setSVMDetector(cv::HOGDescriptor::getDefaultPeopleDetector());
|
||||
std::cout << "going to use HOG detector." << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
cv::FileStorage fs(cascadePath, cv::FileStorage::READ);
|
||||
if( !fs.isOpened())
|
||||
{
|
||||
std::cout << "Soft Cascade file " << cascadePath << " can't be opened." << std::endl << std::flush;
|
||||
return 1;
|
||||
}
|
||||
|
||||
cascade = cv::softcascade::Detector(minScale, maxScale, scales, cv::softcascade::Detector::DOLLAR);
|
||||
|
||||
if (!cascade.load(fs.getFirstTopLevelNode()))
|
||||
{
|
||||
std::cout << "Soft Cascade can't be parsed." << std::endl << std::flush;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
std::string src = parser.get<std::string>("frame");
|
||||
std::vector<cv::String> frames;
|
||||
cv::glob(parser.get<std::string>("frame"), frames);
|
||||
std::cout << "collected " << src << " " << frames.size() << " frames." << std::endl;
|
||||
|
||||
for (int i = 0; i < (int)frames.size(); ++i)
|
||||
{
|
||||
std::string frame_sourse = frames[i];
|
||||
cv::Mat frame = cv::imread(frame_sourse);
|
||||
|
||||
if(frame.empty())
|
||||
{
|
||||
std::cout << "Frame source " << frame_sourse << " can't be opened." << std::endl << std::flush;
|
||||
continue;
|
||||
}
|
||||
|
||||
std::ofstream myfile;
|
||||
if (wf)
|
||||
myfile.open((frame_sourse.replace(frame_sourse.end() - 3, frame_sourse.end(), "txt")).c_str(), std::ios::out);
|
||||
|
||||
////
|
||||
if (useHOG)
|
||||
{
|
||||
std::vector<cv::Rect> found, found_filtered;
|
||||
// run the detector with default parameters. to get a higher hit-rate
|
||||
// (and more false alarms, respectively), decrease the hitThreshold and
|
||||
// groupThreshold (set groupThreshold to 0 to turn off the grouping completely).
|
||||
hog.detectMultiScale(frame, found, 0, cv::Size(8,8), cv::Size(32,32), 1.05, 2);
|
||||
|
||||
filter_rects(found, found_filtered);
|
||||
std::cout << "collected: " << (int)found_filtered.size() << " detections." << std::endl;
|
||||
|
||||
for (size_t ff = 0; ff < found_filtered.size(); ++ff)
|
||||
{
|
||||
cv::Rect r = found_filtered[ff];
|
||||
cv::rectangle(frame, r.tl(), r.br(), cv::Scalar(0,255,0), 3);
|
||||
|
||||
if (wf) myfile << r.x << "," << r.y << "," << r.width << "," << r.height << "," << 0.f << "\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::vector<cv::softcascade::Detection> objects;
|
||||
cascade.detect(frame, cv::noArray(), objects);
|
||||
std::cout << "collected: " << (int)objects.size() << " detections." << std::endl;
|
||||
|
||||
for (int obj = 0; obj < (int)objects.size(); ++obj)
|
||||
{
|
||||
cv::softcascade::Detection d = objects[obj];
|
||||
|
||||
if(d.confidence > thr)
|
||||
{
|
||||
float b = d.confidence * 1.5f;
|
||||
|
||||
std::stringstream conf(std::stringstream::in | std::stringstream::out);
|
||||
conf << d.confidence;
|
||||
|
||||
cv::rectangle(frame, cv::Rect((int)d.x, (int)d.y, (int)d.w, (int)d.h), cv::Scalar(b, 0, 255 - b, 255), 2);
|
||||
cv::putText(frame, conf.str() , cv::Point((int)d.x + 10, (int)d.y - 5),1, 1.1, cv::Scalar(25, 133, 255, 0), 1, cv::LINE_AA);
|
||||
|
||||
if (wf)
|
||||
myfile << d.x << "," << d.y << "," << d.w << "," << d.h << "," << d.confidence << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (wi) cv::imwrite(frame_sourse + ".dt.png", frame);
|
||||
if (wf) myfile.close();
|
||||
|
||||
if (si)
|
||||
{
|
||||
cv::imshow("pedestrian detector", frame);
|
||||
cv::waitKey(10);
|
||||
}
|
||||
}
|
||||
|
||||
if (si) cv::waitKey(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void filter_rects(const std::vector<cv::Rect>& candidates, std::vector<cv::Rect>& objects)
|
||||
{
|
||||
size_t i, j;
|
||||
for (i = 0; i < candidates.size(); ++i)
|
||||
{
|
||||
cv::Rect r = candidates[i];
|
||||
|
||||
for (j = 0; j < candidates.size(); ++j)
|
||||
if (j != i && (r & candidates[j]) == r)
|
||||
break;
|
||||
|
||||
if (j == candidates.size())
|
||||
objects.push_back(r);
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 631 KiB After Width: | Height: | Size: 631 KiB |
@@ -1,178 +0,0 @@
|
||||
#include "opencv2/imgproc/imgproc.hpp"
|
||||
#include "opencv2/calib3d/calib3d.hpp"
|
||||
#include "opencv2/contrib/contrib.hpp"
|
||||
#include "opencv2/highgui/highgui.hpp"
|
||||
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
#include <ctime>
|
||||
|
||||
using namespace cv;
|
||||
using namespace std;
|
||||
|
||||
static
|
||||
void cvtDepth2Cloud( const Mat& depth, Mat& cloud, const Mat& cameraMatrix )
|
||||
{
|
||||
const float inv_fx = 1.f/cameraMatrix.at<float>(0,0);
|
||||
const float inv_fy = 1.f/cameraMatrix.at<float>(1,1);
|
||||
const float ox = cameraMatrix.at<float>(0,2);
|
||||
const float oy = cameraMatrix.at<float>(1,2);
|
||||
cloud.create( depth.size(), CV_32FC3 );
|
||||
for( int y = 0; y < cloud.rows; y++ )
|
||||
{
|
||||
Point3f* cloud_ptr = (Point3f*)cloud.ptr(y);
|
||||
const float* depth_prt = (const float*) depth.ptr(y);
|
||||
for( int x = 0; x < cloud.cols; x++ )
|
||||
{
|
||||
float z = depth_prt[x];
|
||||
cloud_ptr[x].x = (x - ox) * z * inv_fx;
|
||||
cloud_ptr[x].y = (y - oy) * z * inv_fy;
|
||||
cloud_ptr[x].z = z;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<class ImageElemType>
|
||||
static void warpImage( const Mat& image, const Mat& depth,
|
||||
const Mat& Rt, const Mat& cameraMatrix, const Mat& distCoeff,
|
||||
Mat& warpedImage )
|
||||
{
|
||||
const Rect rect = Rect(0, 0, image.cols, image.rows);
|
||||
|
||||
vector<Point2f> points2d;
|
||||
Mat cloud, transformedCloud;
|
||||
|
||||
cvtDepth2Cloud( depth, cloud, cameraMatrix );
|
||||
perspectiveTransform( cloud, transformedCloud, Rt );
|
||||
projectPoints( transformedCloud.reshape(3,1), Mat::eye(3,3,CV_64FC1), Mat::zeros(3,1,CV_64FC1), cameraMatrix, distCoeff, points2d );
|
||||
|
||||
Mat pointsPositions( points2d );
|
||||
pointsPositions = pointsPositions.reshape( 2, image.rows );
|
||||
|
||||
warpedImage.create( image.size(), image.type() );
|
||||
warpedImage = Scalar::all(0);
|
||||
|
||||
Mat zBuffer( image.size(), CV_32FC1, FLT_MAX );
|
||||
for( int y = 0; y < image.rows; y++ )
|
||||
{
|
||||
for( int x = 0; x < image.cols; x++ )
|
||||
{
|
||||
const Point3f p3d = transformedCloud.at<Point3f>(y,x);
|
||||
const Point p2d = pointsPositions.at<Point2f>(y,x);
|
||||
if( !cvIsNaN(cloud.at<Point3f>(y,x).z) && cloud.at<Point3f>(y,x).z > 0 &&
|
||||
rect.contains(p2d) && zBuffer.at<float>(p2d) > p3d.z )
|
||||
{
|
||||
warpedImage.at<ImageElemType>(p2d) = image.at<ImageElemType>(y,x);
|
||||
zBuffer.at<float>(p2d) = p3d.z;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
float vals[] = {525., 0., 3.1950000000000000e+02,
|
||||
0., 525., 2.3950000000000000e+02,
|
||||
0., 0., 1.};
|
||||
|
||||
const Mat cameraMatrix = Mat(3,3,CV_32FC1,vals);
|
||||
const Mat distCoeff(1,5,CV_32FC1,Scalar(0));
|
||||
|
||||
if( argc != 5 && argc != 6 )
|
||||
{
|
||||
cout << "Format: image0 depth0 image1 depth1 [transformationType]" << endl;
|
||||
cout << "Depth file must be 16U image stored depth in mm." << endl;
|
||||
cout << "Transformation types:" << endl;
|
||||
cout << " -rbm - rigid body motion (default)" << endl;
|
||||
cout << " -r - rotation rotation only" << endl;
|
||||
cout << " -t - translation only" << endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
Mat colorImage0 = imread( argv[1] );
|
||||
Mat depth0 = imread( argv[2], -1 );
|
||||
|
||||
Mat colorImage1 = imread( argv[3] );
|
||||
Mat depth1 = imread( argv[4], -1 );
|
||||
|
||||
if( colorImage0.empty() || depth0.empty() || colorImage1.empty() || depth1.empty() )
|
||||
{
|
||||
cout << "Data (rgb or depth images) is empty.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
int transformationType = RIGID_BODY_MOTION;
|
||||
if( argc == 6 )
|
||||
{
|
||||
string ttype = argv[5];
|
||||
if( ttype == "-rbm" )
|
||||
{
|
||||
transformationType = RIGID_BODY_MOTION;
|
||||
}
|
||||
else if ( ttype == "-r")
|
||||
{
|
||||
transformationType = ROTATION;
|
||||
}
|
||||
else if ( ttype == "-t")
|
||||
{
|
||||
transformationType = TRANSLATION;
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << "Unsupported transformation type." << endl;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
Mat grayImage0, grayImage1, depthFlt0, depthFlt1/*in meters*/;
|
||||
cvtColor( colorImage0, grayImage0, COLOR_BGR2GRAY );
|
||||
cvtColor( colorImage1, grayImage1, COLOR_BGR2GRAY );
|
||||
depth0.convertTo( depthFlt0, CV_32FC1, 1./1000 );
|
||||
depth1.convertTo( depthFlt1, CV_32FC1, 1./1000 );
|
||||
|
||||
TickMeter tm;
|
||||
Mat Rt;
|
||||
|
||||
vector<int> iterCounts(4);
|
||||
iterCounts[0] = 7;
|
||||
iterCounts[1] = 7;
|
||||
iterCounts[2] = 7;
|
||||
iterCounts[3] = 10;
|
||||
|
||||
vector<float> minGradMagnitudes(4);
|
||||
minGradMagnitudes[0] = 12;
|
||||
minGradMagnitudes[1] = 5;
|
||||
minGradMagnitudes[2] = 3;
|
||||
minGradMagnitudes[3] = 1;
|
||||
|
||||
const float minDepth = 0.f; //in meters
|
||||
const float maxDepth = 4.f; //in meters
|
||||
const float maxDepthDiff = 0.07f; //in meters
|
||||
|
||||
tm.start();
|
||||
bool isFound = cv::RGBDOdometry( Rt, Mat(),
|
||||
grayImage0, depthFlt0, Mat(),
|
||||
grayImage1, depthFlt1, Mat(),
|
||||
cameraMatrix, minDepth, maxDepth, maxDepthDiff,
|
||||
iterCounts, minGradMagnitudes, transformationType );
|
||||
tm.stop();
|
||||
|
||||
cout << "Rt = " << Rt << endl;
|
||||
cout << "Time = " << tm.getTimeSec() << " sec." << endl;
|
||||
|
||||
if( !isFound )
|
||||
{
|
||||
cout << "Rigid body motion cann't be estimated for given RGBD data." << endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
Mat warpedImage0;
|
||||
warpImage<Point3_<uchar> >( colorImage0, depthFlt0, Rt, cameraMatrix, distCoeff, warpedImage0 );
|
||||
|
||||
imshow( "image0", colorImage0 );
|
||||
imshow( "warped_image0", warpedImage0 );
|
||||
imshow( "image1", colorImage1 );
|
||||
waitKey();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Before Width: | Height: | Size: 102 KiB |
|
Before Width: | Height: | Size: 100 KiB |
|
Before Width: | Height: | Size: 455 KiB |
|
Before Width: | Height: | Size: 433 KiB |
|
Before Width: | Height: | Size: 109 KiB After Width: | Height: | Size: 109 KiB |
|
Before Width: | Height: | Size: 109 KiB After Width: | Height: | Size: 109 KiB |