2013-03-07 2 views
2

안녕하세요 SURF 설명자에서 데이터를 추출하려고하는데 ORB 설명자를 사용하여 이것을 시도하면 작동합니다. SURF를 사용할 때 프로그램은 base64 인 코드 행에서 세그먼트 화 오류 11로 종료되고이 사이트의 base64 함수를 사용합니다 (Encoding and decoding base64).인코딩 CV_32FC1 mat64 데이터 (base64)

ORB 디스크립터의 형식은 CV_8UC1이고 SURF 디스크립터는 CV_32FC1입니다. 그래서 base64는 8 비트 부호없는 char 대신 32 비트 float을 인코딩해야합니다.

어떻게하면됩니까?

Mat desc; 
vector<KeyPoint> kp; 

SurfFeatureDetector detector(500); 
SurfDescriptorExtractor extractor; 
// OrbDescriptorExtractor extractor; This works 

detector.detect(image, kp); 
extractor.compute(image, kp, desc); 

desc.convertTo(desc, CV_8UC1, 255, 0); 

unsigned char const* inBuffer = reinterpret_cast<unsigned char const*>(desc.data); 
unsigned int in_len = desc.total(); 
string code = base64_encode(inBuffer, in_len).c_str(); // This line causes the error 
+0

좀 더 구체적으로 작성하십시오. 세그 폴트는 어떤 라인에서 발생합니까? – Aurelius

+0

당신이 옳다는 점에 유감스럽게 생각하며, 더 많은 정보로 질문을 업데이트했습니다. – tversteeg

+0

설명자 데이터가 'NULL'인 경우에만 segfault를 재현 할 수 있습니다. 또한, 내 편집 된 답변을 참조하십시오. 편집 한 질문이 훨씬 더 정확하고 실제 문제를보다 정확하게 설명합니다. 또한 질문이 "내 코드를 디버그 해주십시오."라는 요청에 부응하지 않으면 좋은 대답을 얻을 가능성이 훨씬 높아집니다. – Aurelius

답변

1

NULL 값을 사용하기 전에 inBuffer 값을 확인하지 않은 것이 하나의 원인 일 수 있습니다. 전달한 이미지에서 설명자가 생성되지 않은 경우 desc.data 및 확장자가 inBuffer 인 경우 NULL이됩니다. 더

몇 가지 :

  1. reinterpret_cast의 사용이 불필요하고, 아마도 안전하지 않습니다. 캐스트 유형에 대한 설명은 this question을 참조하십시오. 당신이 기술자 데이터에 대한 가리키는 const 포인터를 원하는 경우에, 당신은 단순히과 같이 하나를 할당 할 수 있습니다 ORB는 바이너리 디스크립터를 사용하는 반면

    const uchar* inBuffer = desc.data; 
    
  2. SURF는 float 디스크립터를 사용한다. SURF를 사용하려는 경우 코드를 변경해야 할 수 있습니다. inBuffer의 할당은 reinterpret_cast의 사용이 적합 할 수있다이 경우

    const float* inBuffer = reinterpret_cast<const float*>(desc.data); 
    

    로 변경 될 수 있습니다. 그러나 직접 포인터 조작을 수행하지 않는 한 직접 포인터 조작을하지 않는 것이 좋습니다. 요소 액세스에는 cv::Mat_<float>을 사용하는 것이 좋습니다.

편집 : 업데이트 된 질문에 비추어은 지점이 덜 관련이있다. 추가 문제가 발생합니다. float에서 uchar을 통해 convertTo()을 (를) 변환하면 정보가 손실됩니다. 이 경우 변환은 설명자 데이터의 원래 정밀도를 복구 할 수 없게합니다. base64 인코딩이 작동한다고 가정 할 때 이전처럼 디스크립터 데이터를 간단하게 처리 할 수는 있지만 이는이 질문의 범위를 벗어납니다.

+0

더 많은 정보를 추가해야 할 수도 있습니다. base64 인 코드 함수를 사용하여 Mat 데이터를 전송합니다 :'string base64_encode (unsigned char const * bytes_to_encode, unsigned int in_len)'하지만 정보를 잃지 않고 float를 바이트로 캐스팅 할 수 있습니까? – tversteeg

0
cv::initModule_nonfree(); //Patent protection related. 

(예를 들어 opencv_nonfree243.lib를) 라이브러리를 포함하는 것을 잊지 마십시오.

+0

'#include '를 추가해야하고 코드를 추가했지만 여전히 세그먼트 화 오류가 발생합니다. – tversteeg