2014-10-07 3 views
1

postgresql 데이터베이스에서 가져온 C++ opencv에서 이미지를로드하려고합니다. 이미지 (jpg 확장자)는 libpqxx 덕분에 액세스 할 수있는베이스에 바이너리 데이터 (bytea 유형)로 저장됩니다.opencv 이진 데이터 jpg 이미지를 cv :: Mat

문제는 데이터를 cv :: Mat 인스턴스로 변환하는 방법을 모른다는 것입니다. 일반 이미지를 사용하면 imread ('myImage.jpg', ...)를 사용할 수 있지만이 경우 jpeg가 아니고 bmp이기 때문에 Mat의 데이터 속성에 데이터베이스 이미지를로드 할 수도 없습니다.

아이디어가 있으십니까? 이진 데이터를 직접 이해하고 적절한 구조로 변환 할 수있는 opencv 메서드가 있습니까? imdecode() 함수는 비트 맵 데이터에 사용되는 것 같습니다.

편집 : Berak, 벡터를 사용하여 imdecode 함수가 null을 반환합니다. Matrice "버퍼가 너무 짧거나 유효하지 않은 데이터가 포함 된 경우 빈 행렬/이미지가 반환됩니다." 코드는 다음과 같습니다.

pqxx::result r=bdd::requete("SELECT image FROM lrad.img WHERE id=3",1);//returns the bytea image in r[0]["image"] 
const char* buffer=r[0]["image"].c_str();  
vector<uchar>::size_type size = strlen((const char*)buffer); 
vector<uchar> jpgbytes(buffer, buffer+size); 
Mat img = imdecode(jpgbytes, CV_LOAD_IMAGE_COLOR); 
//jpgbytes.size()=1416562 img.size()=[0 x 0] 

무엇이 누락 되었습니까?

+0

어떻게 이미지를 저장 했습니까? (sql 유형) – berak

답변

3

여전히 사용하려면 imdecode을 사용하십시오. 그것은 png, jpg, bmp, ppm, webp, jp2, exr을 처리 할 수 ​​있지만 gif는 사용할 수 없습니다.

vector<uchar> jpgbytes; // from your db 
Mat img = imdecode(jpgbytes); 

는 (당신은 매트의 원시 데이터 포인터와 혼란하지, BMP 또는 지원되는 다른 형식에 대해 동일한 작업을 수행해야한다!)

+0

이 충분하지 않습니다. 내 요청 결과를 벡터 으로 변환했지만 imdecode가 데이터를 이해하지 못합니다. – alexis

+1

데이터에 *가 * 있습니까? 어떤 추가 base64 인코딩이있을 수 있습니까? imdecode는 디스크의 이미지와 동일합니다. – berak

+1

const char * buffer = r [0] [ "이미지"] .c_str(); // <- 바이너리 데이터 인 경우 처음 0에서 자릅니다. – berak

1

좋아 나는 이력서에 bytea와 데이터를 변환 할 수있는 프로세스를 : 매트, 여기에 코드가 있습니다.

inline int dec(uchar x){ //convert uchar to int 
    if (x>='0'&&x<='9') return (x-'0'); 
    else if (x>='a'&&x<='f') return (x-'a'+10); 
    else if (x>='A'&&x<='F') return (x-'A'+10); 
    return 0; 
} 
cv::Mat bytea2Mat(const pqxx::result::field& f){ 
    const char* buffer=f.c_str(); 
    vector<uchar>::size_type size = strlen((const char*)buffer); 
    vector<uchar> jpgbytes(size/2-1); 

    for (size_t i=0; i!=size/2-1;i++) { 
     jpgbytes[i]=(dec(buffer[2*(i+1)])<<4)+dec(buffer[2*(i+1)+1]); 
    } 
    cout <<size/2<<";"<<jpgbytes.size()<<endl; 
    return imdecode(jpgbytes, CV_LOAD_IMAGE_COLOR); 
} 

BYTEA 출력 헥사 형태의 "B0"의 일본어 입력 문자열은 "\의 x41204230"처럼 보이는 숯불 *로 암호화된다. (\ x는 데이터 입력에 따라 표시되지 않을 수 있습니다.) 원본 데이터를 가져 오려면 두 개의 문자 ('4', '1'= 0x41 = 65)에서 원래 입력을 계산해야합니다. 벡터는 char *의 절반 크기입니다.

관련 문제