CV_32FC1 cvMat에 SVD를 적용하고 'u'구성 요소의 일부 값을 수정했습니다. 이제는 단일 행렬 A를 얻기 위해 'u, w'및 'vt'구성 요소를 곱하려고합니다. 그러나 OpenCV는 행렬에 다음 오류를 곱하지 못합니다. OpenCV에서 행렬의 SVD 구성 요소 곱하기
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 객체의 행렬의 유형을 검사
, 그들은 기본 매트릭스 형식의 일치하지 않는 유형 = 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;
}
구성 요소를 수정하지 않으면 작동합니까? – DRVic
@DRVic 아니요 둘 중 하나도 작동하지 않습니다. – blacktooth
글쎄, 그건 단서가됩니다. 요소를 수정하는 것이 아닙니다. 나는 당신이 SVD를 얻으려는 루틴에 대해 많이 알지 못한다. 그러나 나는 루프 안에서'SVD temp (dst, 5); '를 호출하는 것을 방해하고 svd [i에 결과를 할당한다. ], 그 후에 temp는 범위를 벗어날 수 있습니다. svd [i]의 복사본이 완전한 복사본을 작성합니까? – DRVic