我正在进行特征提取和比较。现在我需要提取数据库中的图像特征(mysql)。在数据库中我有很多图像,我正在检索那些图像并将其作为特征提取函数的参数传递。但问题是,在数据库中我将图像存储为二进制数据(blob).SO当我检索到我我正在将二进制图像数据写入文件指针。因此我无法将其传递给特征提取功能。如何将其转换为Mat图像格式。 这是我的代码:
#include <mysql/mysql.h>
#include<iostream>
#include <stdio.h>
#include<cv.h>
#include <sys/time.h>
#include<highgui.h>
#include<stdlib.h>
#include<sys/types.h>
#include<fstream>
#include<string.h>
#include<unistd.h>
#include "opencv2/core/core.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/nonfree/features2d.hpp"
#include "opencv2/core/mat.hpp"
using namespace std;
using namespace cv;
void InsertImage(string);
void SelectImage(Mat img);
void ImgInsert(MYSQL *conn,char* buff);
void FeatureExtract( Mat img_1, Mat img_2);
static int i=1;
static int k1=1;
char data[1000*1024];
char chunk[2*1000*1024+1];
char query[1024*5000];
int main(int argc, char*argv[])
{
Mat img=imread(argv[1],CV_LOAD_IMAGE_COLOR);
InsertImage("ls -A /home/athira/Image/OutputImage");
SelectImage(img);
return 0;
}
void InsertImage(string cmd)
{
MYSQL *conn;
char buf[128];
int len, size;
char data[1000*1024];
char chunk[2*1000*1024+1];
char query[1024*5000];
FILE *fp;
conn = mysql_init(NULL);//initializing connection variable
mysql_real_connect(conn, "localhost", "root", "athira@iot", "Athira", 0, NULL, 0);//establishing connection
cout<<"Connecting to database.."<<endl;
char path[255]="/home/athira/Image/OutputImage";
char buff[1000];
FILE *pipe=popen(cmd.c_str(),"r");
if(!pipe)
cout<<"ERROR"<<endl;;
while(fgets(buf,128,pipe)!=NULL)
{
len=strlen(buf);
if(buf[len-1]=='\n')
{
buf[len-1]='\0';
}
sprintf(buff,"%s/%s",path,buf);
cout<<buff<<endl;
ImgInsert(conn,buff);
}
mysql_close(conn);
}
void ImgInsert(MYSQL *conn,char* buff){
int len, size;
FILE *fp;
fp = fopen(buff, "rb");//open file for reading.
size = fread(data, 1, 1024*1000, fp);
mysql_real_escape_string(conn, chunk, data, size);
char *stat = "INSERT INTO images(id, data) VALUES(%d, '%s')";
len = snprintf(query, sizeof(stat)+sizeof(chunk) , stat,i, chunk);
mysql_real_query(conn, query, len);//Executes the SQL statement
cout<<"inserted.."<<i<<endl;
i++;
fclose(fp);
}
void SelectImage(Mat img)
{
//create an image file from the database.
MYSQL *conn;
MYSQL_RES *result;
MYSQL_ROW row;
char temp[900];
char filename[50];
//int state;
unsigned long *lengths;
FILE *fp;
my_ulonglong numRows;
unsigned int numFields;
int mysqlStatus = 0;
MYSQL_RES *mysqlResult = NULL;
conn = mysql_init(NULL);
mysql_real_connect(conn, "localhost", "root", "athira@iot", "Athira", 0, NULL, 0);
//int state=mysql_query(conn, "SELECT count(*) FROM images");
int state=mysql_query(conn, "SELECT * FROM images");
mysqlResult=mysql_store_result(conn);
if(mysqlResult)
{
numRows=mysql_num_rows(mysqlResult);
}
cout<<"rows:"<<numRows<<endl;
for(int i=1;i<=numRows;i++){
sprintf(temp,"SELECT data FROM images WHERE id=%d",i);
sprintf(filename,"Gen_Image%d.jpeg",i);
fp = fopen(filename, "wb");// open a file for writing.
cout<<temp<<" to "<<filename<<endl;
mysql_query(conn, temp);//select an image with id
result = mysql_store_result(conn);
row = mysql_fetch_row(result);//row contains row data
lengths = mysql_fetch_lengths(result);//this is the length of th image
fwrite(row[0], lengths[0], 1, fp);//writing image to a file
Mat re=(Mat)fp; //this conversion is not working
FeatureExtract(img,re);
cout<<"selected..."<<endl;
mysql_free_result(result);
fclose(fp);
}
mysql_close(conn);
}
void FeatureExtract( Mat img_1, Mat img_2)
{
cout<<"here.."<<endl;
if( !img_1.data || !img_2.data )
{
std::cout<< " --(!) Error reading images " << std::endl;
}
//-- Step 1: Detect the keypoints using SURF Detector
int minHessian = 400;
SurfFeatureDetector detector( minHessian );
std::vector<KeyPoint> keypoints_1, keypoints_2;
detector.detect( img_1, keypoints_1 );
detector.detect( img_2, keypoints_2 );
//-- Step 2: Calculate descriptors (feature vectors)
SurfDescriptorExtractor extractor;
Mat descriptors_1, descriptors_2;
extractor.compute( img_1, keypoints_1, descriptors_1 );
extractor.compute( img_2, keypoints_2, descriptors_2 );
//-- Step 3: Matching descriptor vectors using FLANN matcher
FlannBasedMatcher matcher;
std::vector< DMatch > matches;
matcher.match( descriptors_1, descriptors_2, matches );
double max_dist = 0; double min_dist = 100;
//-- Quick calculation of max and min distances between keypoints
for( int i = 0; i < descriptors_1.rows; i++ )
{
double dist = matches[i].distance;
if( dist < min_dist ) min_dist = dist;
if( dist > max_dist ) max_dist = dist;
}
printf("-- Max dist : %f \n", max_dist );
printf("-- Min dist : %f \n", min_dist );
if((max_dist && min_dist) == 0)
{
std::cout<<"Matching"<<std::endl;
}
else
{
std::cout<<"Not Matching"<<std::endl;
}
std::vector< DMatch > good_matches;
for( int i = 0; i < descriptors_1.rows; i++ )
{ if( matches[i].distance <= max(2*min_dist, 0.02) )
{ good_matches.push_back( matches[i]); }
}
Mat img_matches;
drawMatches( img_1, keypoints_1, img_2, keypoints_2,
good_matches, img_matches, Scalar::all(-1), Scalar::all(-1),
vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );
for(size_t i = 0; i < good_matches.size(); i++)
{
Point2f point1 = keypoints_1[good_matches[i].queryIdx].pt;
Point2f point2 = keypoints_2[good_matches[i].trainIdx].pt;
std::cout<<"X:"<<good_matches[i].queryIdx<<std::endl;
std::cout<<"Y:"<<good_matches[i].trainIdx<<std::endl;
}
imshow( "Good Matches", img_matches );
for( int i = 0; i < (int)good_matches.size(); i++ )
{
//printf( "-- Good Match [%d] Keypoint 1: %d -- Keypoint 2: %d \n", i, good_matches[i].queryIdx, good_matches[i].trainIdx );
}
waitKey(0);
}