0

私はスペクトルカメラに取り組んでおり、opencv を使用して処理を行っています。私はopencvを使い始めたばかりなので、これが最善の方法ではないかもしれません。

基本的に、このコードは 2 つのビデオ ストリームからフレームを取得し、行列の乗算を行います。captureF と captureM はどちらもビデオ ストリームであり、eigen は 6x7 の行列で、最後の行は画像から減算する必要があるオフセットです。

2 つのフレームを 1 つの 6 チャネル イメージに結合する方法がわかりませんでした (マージ チャネルとミックスチャネルを調べましたが、どちらも機能しませんでした)。そのため、行列の乗算を手動で行い、データを 2 つの 3 チャネル イメージに保存することになりました。 、しかし理想的には、これは 1 つの 6 チャネル マトリックスになります。私の質問は、このコードは現在非常に遅く (1 フレームあたり 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));
        }
4

1 に答える 1

0

私はopencv2を使用しており、初心者なので、もっと良い方法があるかもしれません。必要に応じて、古い cv に転置することもできると思います。まず、6 チャネルのスカラーがないように見えます。したがって、データを NX6 配列 (N = 行 * 列) に変換し、行列乗算を使用します。

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!
于 2012-05-16T16:02:06.197 に答える