2012-05-01 2 views
10

OpenCV 2.3.1을 사용하여 12 비트 바이어 이미지를 8 비트 RGB 이미지로 변환하려고합니다. 그것은 cvCvtColor 기능을 사용하여 매우 간단합니다 같은이 보이지만, 함수는이 코드로 호출 예외가 발생합니다 :OpenCV를 사용하여 12 비트 바이어 이미지를 8 비트 RGB로 변환

int cvType = CV_MAKETYPE(CV_16U, 1); 
cv::Mat bayerSource(height, width, cvType, sourceBuffer); 
cv::Mat rgbDest(height, width, CV_8UC3); 
cvCvtColor(&bayerSource, &rgbDest, CV_BayerBG2RGB); 

내가 입력 데이터 이후, sourceBuffer의 끝을지나 실행 된 생각을 OpenCV에는 12 비트 유형이 없기 때문에 12 비트이고 16 비트 유형을 전달해야했습니다. 그래서 너비와 높이를 2로 나누었지만 cvCvtColor는 여전히 유용한 정보가없는 예외를 던졌습니다 (오류 메시지는 "알 수없는 예외"였습니다).

몇 달 전에 게시 된 similar question은 답변이 없었지만, 제 질문은 12 비트 바이엘 데이터를보다 구체적으로 다루기 때문에 새로운 질문을 제시하는 데 충분하다고 생각했습니다.

미리 감사드립니다.

cv::Mat srcMat(100, 100, CV_8UC3); 
const cv::Scalar val(255,0,0); 
srcMat.setTo(val); 
cv::Mat destMat(100, 100, CV_8UC3); 
cvCvtColor(&srcMat, &destMat, CV_RGB2BGR); 
+2

그래서 그것이 내가 * 뭔가를 잃어버린 * 밝혀 :

수정 Gillfish의 코드는 (카메라를 가정하고 16 비트 바이엘 인코딩 이미지를 제공합니다). 동료는 C 및 C++ 호출을 혼합한다고 지적했습니다. 마지막 줄을 으로 변경하십시오. cv :: cvtColor (srcMat, destMat, CV_RGB2BGR); 모든 것이 매력처럼 작동합니다. 나는 여전히 16 비트 바이어스 데이터를 8 비트 RGB 데이터로 변환한다는 원래의 문제에 대해 연구 중이므로 이에 대한 답을 찾으면 업데이트를 게시 할 것입니다. – Gillfish

+2

'cvCvtColor'는 오래된 C OpenCV API에 속하지만'cv :: Mat'은 C++ API의 클래스입니다. 그것들을 혼합하는 것은 좋은 생각이 아니므로 한 가지 버전의 API 만 사용하는 것이 좋습니다. 'cv :: cvtColor (srcMat, dstMat, COLOR_RGB2BGR)'가 잘 동작 할 것입니다. –

+0

"녹색 필터 모양"은 아마도 잘못된 바이어 패턴을 지정했음을 의미합니다. 모두 시도해보십시오. – user3443369

답변

3

Gillfish의 대답은 기술적으로는 작동하지만 변환하는 동안 입력 (CV_16UC1)보다 작은 데이터 구조 (CV_8UC1)를 사용하고 색 정보가 손실됩니다.

먼저 바이어 인코딩을 해독하되 채널 당 16 비트 (CV_16UC1에서 CV_16UC3까지)로 유지하고 나중에 CV_8UC3으로 변환하는 것이 좋습니다.

// Copy the data into an OpenCV Mat structure 
cv::Mat mat16uc1_bayer(height, width, CV_16UC1, inputBuffer); 

// Decode the Bayer data to RGB but keep using 16 bits per channel 
cv::Mat mat16uc3_rgb(width, height, CV_16UC3); 
cv::cvtColor(mat16uc1_bayer, mat16uc3_rgb, cv::COLOR_BayerGR2RGB); 

// Convert the 16-bit per channel RGB image to 8-bit per channel 
cv::Mat mat8uc3_rgb(width, height, CV_8UC3); 
mat16uc3_rgb.convertTo(mat8uc3_rgb, CV_8UC3, 1.0/256); //this could be perhaps done more effectively by cropping bits 
14

내가 내 데이터를 변환 할 수 있었다 8 비트 :

편집 : 나는 심지어 8 비트 데이터를 작업 할 수있는 cvCvtColor 기능을 얻을 수 없기 때문에 내가 모르는 뭔가가 있어야합니다 다음 코드를 사용하여 RGB는 :

// Copy the data into an OpenCV Mat structure 
cv::Mat bayer16BitMat(height, width, CV_16UC1, inputBuffer); 

// Convert the Bayer data from 16-bit to to 8-bit 
cv::Mat bayer8BitMat = bayer16BitMat.clone(); 
// The 3rd parameter here scales the data by 1/16 so that it fits in 8 bits. 
// Without it, convertTo() just seems to chop off the high order bits. 
bayer8BitMat.convertTo(bayer8BitMat, CV_8UC1, 0.0625); 

// Convert the Bayer data to 8-bit RGB 
cv::Mat rgb8BitMat(height, width, CV_8UC3); 
cv::cvtColor(bayer8Bit, rgb8BitMat, CV_BayerGR2RGB); 

내가 실수로 두 개의 12 비트 값이 3 바이트에 포함 된 있도록 내가 카메라에서 점점 된 12 비트 데이터가 단단히 포장 된 것으로 가정했다. 각 값은 2 바이트로되어 있으므로 OpenCV에서 지원하는 16 비트 배열로 데이터를 가져 오기 위해 언 패킹을 할 필요가 없었습니다.

편집 : 변환 중에 색상 정보가 손실되지 않도록 8 비트로 변환하기 전에 RGB로 변환되는 향상된 답변을 참조하십시오.

+0

나는 여기와 같은 것을하고있다. 그러나 나의 이미지는 녹색의 필터를 가지고있다. 확실하지 않은 이유는 무엇입니까 –

+0

@pksorensen : 관련 문제가있는 경우 그냥 새로운 질문을하고 다시이 문제로 연결하십시오. 그렇게하면 특정 문제에 대한 세부 정보를 추가 할 수 있습니다. – Gillfish

+0

libraw와 opencv로 몇 가지 문제를 겪었을 때 나는 다른 길을 택하고 de-bayer를하기 위해 Nikon SDK를 사용했다. nikons SDK를 사용하면 더 나은 결과를 얻을 수 있었고 같은 결과를 libraw로 얻을 수 없었고 opencv가 기다려야하는 이유를 알 수있었습니다. 어쨌든 고마워. –

관련 문제