2012-05-15 4 views
0

나는 스펙트럼 카메라에서 작업 중이며 opencv를 사용하여 처리합니다. 방금 opencv를 사용하기 시작 했으므로 이것이 최선의 방법은 아닙니다.opencv 여섯 채널 행렬 곱하기

기본적으로이 코드는 두 개의 비디오 스트림에서 프레임을 가져 와서 매트릭스 곱셈을합니다. captureF와 captureM은 모두 비디오 스트림이고 eigen은 마지막 행이 이미지에서 빼는 데 필요한 오프셋 인 6x7 행렬입니다.

2 개의 프레임을 하나의 6 채널 이미지로 결합하는 방법을 알 수 없었습니다. 병합 및 믹스 채널을 살펴 보았지만 작동하지 못함) 수동으로 행렬 곱셈을 수행하고 데이터를 저장했습니다. 두 개의 3 채널 이미지가 있지만 이상적으로 이것은 하나의 6 채널 매트릭스가됩니다. 내 질문은이 코드는 현재 매우 느린 (프레임 당 20 초) 실행되며 빠른 실행 및 이렇게 6 채널 이미지를 사용하여 작업을 수행 할 수있는 방법이 있는지 궁금해?

 IplImage imgF = cvQueryFrame(captureF); 
     IplImage dst2 = cvQueryFrame(captureM); 


     IplImage *OutImg1 = cvCreateImage(cvSize(imgF->width, imgF->height), IPL_DEPTH_32F, 3); 
     IplImage *OutImg2 = cvCreateImage(cvSize(imgF->width, imgF->height), IPL_DEPTH_32F, 3); 

     // iterates through each frame in the image. 
     for(int i=0; i<(imgF->imageSize)/3;i+=3){ 
       ((float*)OutImg1->imageData)[i] = cvmGet(eigen,0,2)*(imgF->imageData[i]-cvmGet(eigen,6,2)) + cvmGet(eigen,0,1)*(imgF->imageData[i+1]-cvmGet(eigen,6,1)) + cvmGet(eigen,0,0)*(imgF->imageData[i+2]-cvmGet(eigen,6,0)) + cvmGet(eigen,0,5)*(dst2->imageData[i]-cvmGet(eigen,6,5)) + cvmGet(eigen,0,4)*(dst2->imageData[i+1]-cvmGet(eigen,6,4)) + cvmGet(eigen,0,3)*(dst2->imageData[i+2]-cvmGet(eigen,6,3)); 
       ((float*)OutImg1->imageData)[i+1] = cvmGet(eigen,1,2)*(imgF->imageData[i]-cvmGet(eigen,6,2)) + cvmGet(eigen,1,1)*(imgF->imageData[i+1]-cvmGet(eigen,6,1)) + cvmGet(eigen,1,0)*(imgF->imageData[i+2]-cvmGet(eigen,6,0)) + cvmGet(eigen,1,5)*(dst2->imageData[i]-cvmGet(eigen,6,5)) + cvmGet(eigen,1,4)*(dst2->imageData[i+1]-cvmGet(eigen,0,4)) + cvmGet(eigen,1,3)*(dst2->imageData[i+2]-cvmGet(eigen,6,3)); 
       ((float*)OutImg1->imageData)[i+2] = cvmGet(eigen,2,2)*(imgF->imageData[i]-cvmGet(eigen,6,2)) + cvmGet(eigen,2,1)*(imgF->imageData[i+1]-cvmGet(eigen,6,1)) + cvmGet(eigen,2,0)*(imgF->imageData[i+2]-cvmGet(eigen,6,0)) + cvmGet(eigen,2,5)*(dst2->imageData[i]-cvmGet(eigen,6,5)) + cvmGet(eigen,2,4)*(dst2->imageData[i+1]-cvmGet(eigen,0,4)) + cvmGet(eigen,2,3)*(dst2->imageData[i+2]-cvmGet(eigen,6,3)); 

       ((float*)OutImg2->imageData)[i] = cvmGet(eigen,3,2)*(imgF->imageData[i]-cvmGet(eigen,6,2)) + cvmGet(eigen,3,1)*(imgF->imageData[i+1]-cvmGet(eigen,6,1)) + cvmGet(eigen,3,0)*(imgF->imageData[i+2]-cvmGet(eigen,6,0)) + cvmGet(eigen,3,5)*(dst2->imageData[i]-cvmGet(eigen,6,5)) + cvmGet(eigen,3,4)*(dst2->imageData[i+1]-cvmGet(eigen,0,4)) + cvmGet(eigen,3,3)*(dst2->imageData[i+2]-cvmGet(eigen,6,3)); 
       ((float*)OutImg2->imageData)[i+1] = cvmGet(eigen,4,2)*(imgF->imageData[i]-cvmGet(eigen,6,2)) + cvmGet(eigen,4,1)*(imgF->imageData[i+1]-cvmGet(eigen,6,1)) + cvmGet(eigen,4,0)*(imgF->imageData[i+2]-cvmGet(eigen,6,0)) + cvmGet(eigen,4,5)*(dst2->imageData[i]-cvmGet(eigen,6,5)) + cvmGet(eigen,4,4)*(dst2->imageData[i+1]-cvmGet(eigen,0,4)) + cvmGet(eigen,4,3)*(dst2->imageData[i+2]-cvmGet(eigen,6,3)); 
       ((float*)OutImg2->imageData)[i+2] = cvmGet(eigen,5,2)*(imgF->imageData[i]-cvmGet(eigen,6,2)) + cvmGet(eigen,5,1)*(imgF->imageData[i+1]-cvmGet(eigen,6,1)) + cvmGet(eigen,5,0)*(imgF->imageData[i+2]-cvmGet(eigen,6,0)) + cvmGet(eigen,5,5)*(dst2->imageData[i]-cvmGet(eigen,6,5)) + cvmGet(eigen,5,4)*(dst2->imageData[i+1]-cvmGet(eigen,0,4)) + cvmGet(eigen,5,3)*(dst2->imageData[i+2]-cvmGet(eigen,6,3)); 
     } 
+0

스펙트럼 카메라 사운드가 정말 멋지다. –

답변

0

나는 opencv2를 사용하며, 랭크 초보자이므로 더 나은 방법이있을 수 있습니다. 네가 필요하다면 네가 옛 이력서로 바꿀 수 있다고 상상해. 먼저 6 채널 스칼라가 없으므로 성가신 것처럼 보입니다. 따라서 데이터를 NX6 배열 (N = rows * cols)로 변환하고 행렬 곱하기를 사용하십시오.

Mat twoIm[2]; 
Mat eigen(6,6,CV_32F); 
Mat bigGuy,newGuy; 

merge(twoIm,2,bigGuy);   // load your two images into twoIm[0] & twoIm[1] 
bigGuy.convertTo(bigGuy, CV_32F); // mat multiply wants everything the same type 

Mat bigGal = bigGuy.reshape(1, 6); // this makes 6 channels into 6 rows 

newGuy = bigGal.t() * eigen;  // and voila! 
+0

물론 오프셋 벡터를 추가하고 newGuy를 다시 6 채널로 바꿀 수도 있습니다. –

+0

그리고 N = cols * 행으로 재구성 (1, N)하면 안된다. –

+1

행렬을 올바로 구성하기 위해 실제로 변형되었습니다 (1, N). –

관련 문제