Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/128.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将OpenCV中矩阵的SVD分量相乘_C++_Opencv_Matrix_Svd - Fatal编程技术网

C++ 将OpenCV中矩阵的SVD分量相乘

C++ 将OpenCV中矩阵的SVD分量相乘,c++,opencv,matrix,svd,C++,Opencv,Matrix,Svd,我将SVD应用于CV_32FC1 cvMat,并修改了“u”组件中的一些值。现在,我尝试将'u',w'和'vt'分量相乘,得到一个矩阵a。但是OpenCV无法将矩阵相乘,出现以下错误 OpenCV Error: Assertion failed (type == B.type() && (type == CV_32FC1 || type == CV_64FC1 || type == CV_32FC2 || type == CV_64FC2)) in gemm, file /bui

我将SVD应用于CV_32FC1 cvMat,并修改了“u”组件中的一些值。现在,我尝试将'u',w'和'vt'分量相乘,得到一个矩阵a。但是OpenCV无法将矩阵相乘,出现以下错误

OpenCV Error: Assertion failed (type == B.type() && (type == CV_32FC1 || type == CV_64FC1 || type == CV_32FC2 || type == CV_64FC2)) in gemm, file /build/buildd/opencv-2.1.0/src/cxcore/cxmatmul.cpp, line 687
terminate called after throwing an instance of 'cv::Exception'
  what():  /build/buildd/opencv-2.1.0/src/cxcore/cxmatmul.cpp:687: error: (-215) type == B.type() && (type == CV_32FC1 || type == CV_64FC1 || type == CV_32FC2 || type == CV_64FC2) in function gemm
当我检查SVD对象中的矩阵类型时,它们的type=20,这与任何默认矩阵类型都不匹配

#include <iostream>
#include <stdio.h>
#include "cv.h"
#include "highgui.h"
#include "constants.h"

const unsigned int MAX = 10000;

using namespace cv;
using namespace std;

int NO_FRAMES;

Mat resize_image(Mat &src, Mat img)
{
    Mat dst;
    resize(src, dst, Size(img.rows, img.cols));
    return dst;
}

bool check_exit()
{
     return (waitKey(27) > 0)?true:false;
}

int main(int argc, char ** argv)
{
    Mat rgb[MAX];
    Mat ycbcr[MAX];
    Mat wm_rgb[MAX];
    SVD svd[MAX];
    namedWindow("watermark",1);
    namedWindow("RGB", 2);
    namedWindow("YCBCR",3);
    namedWindow("u",4);
    namedWindow("w",5);
    namedWindow("vt",6);
    if (argc < 3)
    {
        cout<<"Video file required! (Supported formats: avi, mp4, mpeg)\n";
        return 1;
    }

    VideoCapture capture(argv[1]);
    Mat watermark = imread(argv[2]);
    if(!capture.isOpened())
    {
        cout<<"Unable to open the video file!\n";
        return 1;
    }

    int i=0;
        capture >> rgb[i];

    while(!rgb[i].empty())
    {
        imshow("RGB", rgb[i]);
        cvtColor(rgb[i], ycbcr[i], CV_RGB2YCrCb);
        imshow("YCBCR", ycbcr[i]);
        i++;
        capture >> rgb[i];

        if(check_exit())
            exit(0);
    }

    NO_FRAMES = i;

    watermark = resize_image(watermark, ycbcr[0]);
    VideoWriter writer("output.avi", CV_FOURCC('d', 'i', 'v', 'x'), 24.0, cvSize(ycbcr[0].cols, ycbcr[0].rows),  true);
    for(int i = 0; i < NO_FRAMES - 1; i++)
    {
        Mat dst(ycbcr[i].rows, ycbcr[i].cols, CV_32FC1);
        ycbcr[i].convertTo(dst, CV_32S); 
        SVD temp(dst, 5);
        imshow("u", temp.u);
        imshow("w", temp.w);
        imshow("vt", temp.vt);
        svd[i] = temp;

        if(check_exit())
            exit(0);
    }


    int j = 0, k = 0;
    for (i = 0; i < NO_FRAMES; i++)
    {
        for (int p = 0; p < svd[i].u.rows; p++)
        {
            for(int q = 0; q < svd[i].u.cols; q++)
            {

                if (p == q)
                {
                    if (j >= watermark.rows)
                    {
                        goto x;
                    }
                    if (k >= watermark.cols)
                    {
                        k = 0;
                        j++;
                    }
                    svd[i].u.at<float>(p, q) = watermark.at<float>(j,k);
                    k++;
                }
            }
        }
    }


x:  for (i = 0; i < NO_FRAMES; i++)
    {
        Mat A(rgb[0].rows, rgb[0].cols, CV_32FC1);

                //Here
                A = svd[i].u * svd[i].w * svd[i].vt;
        Mat B(A.rows, A.cols, CV_32FC1);
        cvtColor(A, B, CV_YCrCb2RGB);
        writer << B;
    }

    capture.release();
    return 0;
}
#包括
#包括
#包括“cv.h”
#包括“highgui.h”
#包括“constants.h”
常量无符号整数最大值=10000;
使用名称空间cv;
使用名称空间std;
int无_帧;
Mat resize_图像(Mat&src、Mat img)
{
Mat-dst;
调整大小(src、dst、Size(img.rows、img.cols));
返回dst;
}
bool check_exit()
{
返回(waitKey(27)>0)?真:假;
}
int main(int argc,字符**argv)
{
Mat rgb[MAX];
Mat ycbcr[MAX];
Mat wm_rgb[MAX];
奇异值奇异值[MAX];
namedWindow(“水印”,1);
namedWindow(“RGB”,2);
命名为“YCBCR”,3;
命名为“u”,4;
命名为“w”,5;
纳梅德温道(“vt”,6);
如果(argc<3)
{
coutrgb[i];
如果(检查_exit())
出口(0);
}
无帧=i;
水印=调整图像大小(水印,ycbcr[0]);
VideoWriter writer(“output.avi”,CV_FOURCC('d','i','v','x'),24.0,cvSize(ycbcr[0].cols,ycbcr[0].rows),true);
对于(int i=0;i=watermark.rows)
{
后藤x;
}
如果(k>=watermark.cols)
{
k=0;
j++;
}
svd[i].u.at(p,q)=水印.at(j,k);
k++;
}
}
}
}
x:for(i=0;iwriter我现在也遇到了这个问题,我想我应该在这里写,在我计算SVD时,我的大小是2*(#imagePixels),
因此,U或Vt矩阵中的一个变得巨大,无法在堆上分配,因此出现了异常std::bad_alloc,在我的例子中,Vt大小将是imagePixels*imagePixels,这是巨大的

愿这也发生在你身上


将此项保留在此处,以便下一个遇到此项的人也可以查看矩阵大小。

错误出现在矩阵乘法运算(gemm())中,尽管错误可能已传播到下一行,您正在尝试使用格式错误的矩阵a创建新矩阵B。 请注意,OpenCV中的SVD算法生成以下形式的输出: 对于矩阵a(m x n),SVD生成以下三个矩阵:

w–计算的奇异值(最小(m,n)x1)

u–计算的左奇异向量(m x m)

vt–右奇异值的转置矩阵(n x n)

这里,奇异值存储在维度(min(m,n)x1)的紧凑列向量中,而不是作为实际的数学等价物,即维度的对角矩阵(min(m,n),min(m,n))

因此,如果要从单个SVD分量重建矩阵,必须首先将向量“w”转换为对角矩阵形式。可以使用OpenCV的diag()方法执行此操作:


如果你不修改任何组件,它能工作吗?@DRVic不,它不能工作。这可能是一个线索:你不是在修改元素。我不太了解你调用的获取SVD的例程,但我发现你调用的是
SVD temp(dst,5);
在循环内,并将结果分配给svd[i],然后允许temp超出范围。是否复制到svd[i]进行深度复制?我删除了temp并直接初始化了svd,但问题仍然存在。我正在运行hsame问题。看起来openCV没有创建完整的u、s、v矩阵以节省内存。我试图使用标志svd::full_UV,但在这种情况下,svd因std::bad_alloc错误而失败。
A = svd[i].u * Mat::diag(svd[i].w) * svd[i].vt;