我对opencv有点新意,可以使用一些帮助。我想检测ASL hand signs。
为了检测手,我可以使用肤色检测或haar分类器。我已经发现了手,但问题是检测到手的形状。
我可以使用here描述的算法获得当前的形状,所以问题是如何将这个形状与我的形状数据库进行比较?
我尝试使用here描述的算法比较它们,该算法检测图像具有的相似特征。问题是,这将与所有的手相匹配,因为......好吧它将它们检测为手。例如,检查此图像,它应该只指向V,但它也会检测W和R中的功能。
我希望我的最终结果与here类似,那么如何比较图像形状呢?我的做法错了吗?
我当时认为通过凸壳检测不起作用,因为大多数标志都是封闭的拳头。例如,检查O,它没有张开的手指,所以我认为尝试比较轮廓将是最好的。但是如何比较它们呢? FLANN似乎不起作用。或者我做错了。
Haar级联分类器是否有效?或者它会检测到不同位置的两只手也是手?
或者是否有另一种匹配形状的方法?这可以解决我的问题,但我找不到任何自定义形状的例子,只适用于矩形,圆形和三角形。
更新
好的,我一直在玩matchShapes,berak告诉我。这是我下面的代码(当前我正在测试它有点乱。)
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace cv;
using namespace std;
Mat src; Mat src_gray;
int thresh = 10;
int max_thresh = 300;
/// Function header
void thresh_callback(int, void* );
/** @function main */
int main( int argc, char** argv )
{
/// Load source image and convert it to gray
src = imread( argv[1], 1 );
/// Convert image to gray and blur it
cvtColor( src, src_gray, CV_BGR2GRAY );
blur( src_gray, src_gray, Size(3,3) );
/// Create Window
char* source_window = "Source";
namedWindow( source_window, CV_WINDOW_AUTOSIZE );
imshow( source_window, src );
createTrackbar( " Canny thresh:", "Source", &thresh, max_thresh, thresh_callback );
thresh_callback( 0, 0 );
waitKey(0);
return(0);
}
/** @function thresh_callback */
void thresh_callback(int, void* )
{
Mat canny_output;
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
double largest_area=0;
int largest_contour_index=0;
Rect bounding_rect;
/// Detect edges using canny
Canny( src_gray, canny_output, thresh, thresh*2, 3 );
/// Find contours
findContours( canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );
cout<<contours.size()<<endl;
/// Draw contours
Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3 );
vector<vector<Point> >hull( contours.size() );
for( int i = 0; i< contours.size(); i++ )
{ Scalar color = Scalar( 255,255,255 );
convexHull( Mat(contours[i]), hull[i], false );
// imshow("conturul"+to_string(i), drawing );
double a=contourArea( hull[i],false); // Find the area of contour
if(a>largest_area){
largest_area=a;
largest_contour_index=i; //Store the index of largest contour
bounding_rect=boundingRect(hull[i]);}
}
cout<<"zaindex "<<largest_contour_index<<endl;
Scalar color = Scalar( 255,255,255 );
drawContours( drawing, hull, largest_contour_index, color, 2, 8, hierarchy, 0, Point() );
namedWindow( "maxim", CV_WINDOW_AUTOSIZE );
imshow( "maxim", drawing );
Mat rects=imread( "scene.png", 1 );
rectangle(rects, bounding_rect, Scalar(0,255,0),1, 8,0);
imshow( "maxim2", rects );
/// Show in a window
}
问题在于轮廓的定义。这些手的“轮廓”实际上是由多个轮廓本身组成的,我之前展示的图像实际上是由这些多个轮廓构成的,但彼此重叠。 matchShapes接受Points数组作为参数,但轮廓是Points数组的数组。
所以我的问题是,我如何添加自己的轮廓矢量,以便将其传递给matchShapes?换句话说,如何从多个重叠轮廓中制作单个轮廓?