C++ OpenCV:使用split()函数进行数据类型断言失败

C++ OpenCV:使用split()函数进行数据类型断言失败,c++,opencv,dft,C++,Opencv,Dft,我在这里尝试遵循离散傅里叶变换(dft)示例: 我正在Windows 8中的Visual Studio 2013 Express上运行2.4.8 我已经修改了这个示例,因此我使用从网络摄像头捕获的彩色图像(加载到Mat变量中),而不是加载灰度图像 当我运行上面的示例时,我得到以下错误: “断言失败Tp>::channels==m.channels())在中 cv::Mat::运算符“ 并在以下行处断开: Mat planes[] = { Mat_<float>(padded), M

我在这里尝试遵循离散傅里叶变换(dft)示例:

我正在Windows 8中的Visual Studio 2013 Express上运行2.4.8

我已经修改了这个示例,因此我使用从网络摄像头捕获的彩色图像(加载到Mat变量中),而不是加载灰度图像

当我运行上面的示例时,我得到以下错误:

“断言失败Tp>::channels==m.channels())在中 cv::Mat::运算符“

并在以下行处断开:

Mat planes[] = { Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F) };
现在的问题是,我在下面几行看到另一个断言失败:

split(complexI, planes); 
错误是:

“断言失败(Type==CV|32FC1 | | Type==CV|32FC2 | |……| | Type ==CV_64FC2)在CV::dft中

所以现在它似乎不喜欢CV_32F数据类型。我尝试创建数据类型CV_32FC1,但它有相同的错误。我怀疑这与dft()函数的complexI输出数据类型有关,但我不确定该怎么办。它也可能与我输入的通道数有关(3通道彩色与1通道灰度图像)

谢谢你的帮助

链接示例中的完整代码:

#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
int main(int argc, char ** argv)
{
    const char* filename = argc >=2 ? argv[1] : "lena.jpg";

    Mat I = imread(filename, CV_LOAD_IMAGE_GRAYSCALE);
    if( I.empty())
        return -1;

    Mat padded;                            //expand input image to optimal size
    int m = getOptimalDFTSize( I.rows );
    int n = getOptimalDFTSize( I.cols ); // on the border add zero values
    copyMakeBorder(I, padded, 0, m - I.rows, 0, n - I.cols, BORDER_CONSTANT, Scalar::all(0));

    Mat planes[] = {Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F)};
    Mat complexI;
    merge(planes, 2, complexI);         // Add to the expanded another plane with zeros

    dft(complexI, complexI);            // this way the result may fit in the source matrix

    // compute the magnitude and switch to logarithmic scale
    // => log(1 + sqrt(Re(DFT(I))^2 + Im(DFT(I))^2))
    split(complexI, planes);                   // planes[0] = Re(DFT(I), planes[1] = Im(DFT(I))
    magnitude(planes[0], planes[1], planes[0]);// planes[0] = magnitude
    Mat magI = planes[0];

    magI += Scalar::all(1);                    // switch to logarithmic scale
    log(magI, magI);

    // crop the spectrum, if it has an odd number of rows or columns
    magI = magI(Rect(0, 0, magI.cols & -2, magI.rows & -2));

    // rearrange the quadrants of Fourier image  so that the origin is at the image center
    int cx = magI.cols/2;
    int cy = magI.rows/2;

    Mat q0(magI, Rect(0, 0, cx, cy));   // Top-Left - Create a ROI per quadrant
    Mat q1(magI, Rect(cx, 0, cx, cy));  // Top-Right
    Mat q2(magI, Rect(0, cy, cx, cy));  // Bottom-Left
    Mat q3(magI, Rect(cx, cy, cx, cy)); // Bottom-Right

    Mat tmp;                           // swap quadrants (Top-Left with Bottom-Right)
    q0.copyTo(tmp);
    q3.copyTo(q0);
    tmp.copyTo(q3);

    q1.copyTo(tmp);                    // swap quadrant (Top-Right with Bottom-Left)
    q2.copyTo(q1);
    tmp.copyTo(q2);

    normalize(magI, magI, 0, 1, CV_MINMAX); // Transform the matrix with float values into a
                                            // viewable image form (float between values 0 and 1).

    imshow("Input Image"       , I   );    // Show the result
    imshow("spectrum magnitude", magI);
    waitKey();

    return 0;
}
#包括“opencv2/core/core.hpp”
#包括“opencv2/imgproc/imgproc.hpp”
#包括“opencv2/highgui/highgui.hpp”
#包括
int main(int argc,字符**argv)
{
const char*filename=argc>=2?argv[1]:“lena.jpg”;
Mat I=imread(文件名、CV\u加载\u图像\u灰度);
if(I.empty())
返回-1;
Mat padded;//将输入图像扩展到最佳大小
int m=getOptimalDFTSize(即行);
int n=getOptimalDFTSize(I.cols);//在边框上添加零值
copyMakeBorder(I,padded,0,m-I.rows,0,n-I.cols,BORDER_常量,Scalar::all(0));
Mat平面[]={Mat_u(padded),Mat::zeros(padded.size(),CV_32F)};
席状复合体;
合并(平面,2,复杂);//添加到扩展的另一个带有零的平面
dft(complexI,complexI);//这样,结果可以适合源矩阵
//计算震级并切换到对数刻度
//=>log(1+sqrt(Re(DFT(I))^2+Im(DFT(I))^2))
拆分(复数,平面);//平面[0]=Re(DFT(I),平面[1]=Im(DFT(I))
幅值(平面[0],平面[1],平面[0]);//平面[0]=幅值
Mat magI=平面[0];
magI+=Scalar::all(1);//切换到对数刻度
日志(magI,magI);
//如果光谱的行数或列数为奇数,则裁剪光谱
magI=magI(Rect(0,0,magI.cols&-2,magI.rows&-2));
//重新排列傅里叶图像的象限,使原点位于图像中心
int cx=magI.cols/2;
int cy=magI.rows/2;
Mat q0(magI,Rect(0,0,cx,cy));//左上角-为每个象限创建一个ROI
Mat q1(magI,Rect(cx,0,cx,cy));//右上角
Mat q2(magI,Rect(0,cy,cx,cy));//左下角
Mat q3(magI,Rect(cx,cy,cx,cy));//右下角
Mat tmp;//交换象限(左上角与右下角)
q0.copyTo(tmp);
q3.复制到(q0);
tmp.copyTo(第三季度);
q1.copyTo(tmp);//交换象限(右上角与左下角)
q2.抄袭(q1);
tmp.copyTo(第2季度);
规格化(magI,magI,0,1,CV_MINMAX);//将带有浮点值的矩阵转换为
//可视图像形式(浮动在值0和1之间)。
imshow(“输入图像”,I);//显示结果
imshow(“光谱幅度”,magI);
waitKey();
返回0;
}

您不能在具有2个以上参数的图像上使用dft

即使图像有两个通道,第二个通道也会被解释为复数的虚部,因此这可能不是您想要的

因此,您有两个选项:要么将从网络摄像头获得的彩色图像转换为单通道图像,如灰度图像,要么对每个通道分别应用dft


您可以查看一下,或者两个都可以从图像中提取单独的通道,然后对每个通道应用dft,

谢谢,我不知道混合通道。我将尝试将它们分离出来,并单独对每个通道进行dft
#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
int main(int argc, char ** argv)
{
    const char* filename = argc >=2 ? argv[1] : "lena.jpg";

    Mat I = imread(filename, CV_LOAD_IMAGE_GRAYSCALE);
    if( I.empty())
        return -1;

    Mat padded;                            //expand input image to optimal size
    int m = getOptimalDFTSize( I.rows );
    int n = getOptimalDFTSize( I.cols ); // on the border add zero values
    copyMakeBorder(I, padded, 0, m - I.rows, 0, n - I.cols, BORDER_CONSTANT, Scalar::all(0));

    Mat planes[] = {Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F)};
    Mat complexI;
    merge(planes, 2, complexI);         // Add to the expanded another plane with zeros

    dft(complexI, complexI);            // this way the result may fit in the source matrix

    // compute the magnitude and switch to logarithmic scale
    // => log(1 + sqrt(Re(DFT(I))^2 + Im(DFT(I))^2))
    split(complexI, planes);                   // planes[0] = Re(DFT(I), planes[1] = Im(DFT(I))
    magnitude(planes[0], planes[1], planes[0]);// planes[0] = magnitude
    Mat magI = planes[0];

    magI += Scalar::all(1);                    // switch to logarithmic scale
    log(magI, magI);

    // crop the spectrum, if it has an odd number of rows or columns
    magI = magI(Rect(0, 0, magI.cols & -2, magI.rows & -2));

    // rearrange the quadrants of Fourier image  so that the origin is at the image center
    int cx = magI.cols/2;
    int cy = magI.rows/2;

    Mat q0(magI, Rect(0, 0, cx, cy));   // Top-Left - Create a ROI per quadrant
    Mat q1(magI, Rect(cx, 0, cx, cy));  // Top-Right
    Mat q2(magI, Rect(0, cy, cx, cy));  // Bottom-Left
    Mat q3(magI, Rect(cx, cy, cx, cy)); // Bottom-Right

    Mat tmp;                           // swap quadrants (Top-Left with Bottom-Right)
    q0.copyTo(tmp);
    q3.copyTo(q0);
    tmp.copyTo(q3);

    q1.copyTo(tmp);                    // swap quadrant (Top-Right with Bottom-Left)
    q2.copyTo(q1);
    tmp.copyTo(q2);

    normalize(magI, magI, 0, 1, CV_MINMAX); // Transform the matrix with float values into a
                                            // viewable image form (float between values 0 and 1).

    imshow("Input Image"       , I   );    // Show the result
    imshow("spectrum magnitude", magI);
    waitKey();

    return 0;
}