如何将二进制图像数据转换为mat图像

时间:2014-03-17 08:53:20

标签: c++ mysql opencv image-processing

我正在进行特征提取和比较。现在我需要提取数据库中的图像特征(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);
}

1 个答案:

答案 0 :(得分:0)

你可能正在寻找imdecode() / imencode()