opencv六通道矩阵乘法

Posted

技术标签:

【中文标题】opencv六通道矩阵乘法【英文标题】:opencv six channel matrix multiply 【发布时间】:2012-05-15 05:36:38 【问题描述】:

我正在使用光谱相机并正在使用 opencv 进行处理。我刚开始使用opencv,所以这可能不是最好的方法。

基本上,这段代码从两个视频流中抓取帧,然后进行矩阵乘法。 captureF 和 captureM 都是视频流,eigen 是一个 6x7 矩阵,其中最后一行是需要从图像中减去的偏移量。

我不知道如何将两个帧组合成一个六通道图像II查看了合并和混合通道但无法工作),所以我最终手动进行矩阵乘法并将数据保存到两个三通道图像,但理想情况下这将是一个 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));
        

【问题讨论】:

光谱相机听起来很酷。 【参考方案1】:

我使用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!

【讨论】:

当然,您可能想要添加偏移向量,并将 newGuy 重新整形为 6 个通道。 而且我不太确定是否不应该使用 N=cols*rows 进行 reshape(1,N)。 实际上是 reshape(1,N) 来正确组织矩阵

以上是关于opencv六通道矩阵乘法的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV逐元素矩阵乘法

OpenCV 断言在矩阵乘法上失败

OpenCV 简单的二维矩阵乘法失败

numpy的矩阵乘法

寻找基本矩阵(矩阵乘法错误)

对OpenCV中3种乘法操作的理解掌握