1

我正在尝试将图像水印到视频序列中。该过程需要将帧分解为 SVD,我试图使用下面的部分代码来实现。第 47 行的 SVD 构造函数因分段错误而失败。gdb 报告以下错误:

“程序收到信号 SIGSEGV,分段错误。来自 /usr/lib/liblapack.so.3gf 的 dlange_ () 中的 0xb5d31ada”

#include <iostream>
#include <stdio.h>
#include "cv.h"
#include "highgui.h"
const unsigned int MAX = 10000;

using namespace cv;
using namespace std;

int NO_FRAMES;

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];
namedWindow("watermark",1);
namedWindow("RGB", 1);
namedWindow("YCBCR",1);
VideoCapture capture(argv[1]);
Mat watermark = imread(argv[2]);
int i=0;
        capture >> rgb[i];
imshow("watermark", watermark);
while(!rgb[i].empty())
{
imshow("RGB", rgb[i]);
cvtColor(rgb[i], ycbcr[i], CV_RGB2YCrCb);
imshow("YCBCR", ycbcr[i]);
i++;
capture >> rgb[i];

cout<<"frame "<<i<<endl;
if(check_exit())
exit(0);
}
//This line creates Segmentation fault
SVD temp(rgb[0]);
capture.release();
return 0;
}
4

1 回答 1

0

由于对 C 接口更加熟悉,我将仅描述一些在您的 C++ 代码中显得格格不入的东西:

SVD() 函数期望输入图像是浮点图像,因此您可能需要将比例从标准的 8 位转换为 32 位。以下是一些非常基本(但不是很有效)的代码,用于说明目的:

int N = img->width;
IplImage* W = cvCreateImage( cvSize(N, 1), IPL_DEPTH_32F , 1 );
IplImage* A = cvCreateImage( cvGetSize(img), IPL_DEPTH_32F , 1 );
cvConvertScale(img, A);

IplImage* W_mod = cvCreateImage( cvSize(N-l, 1), IPL_DEPTH_32F , 1 );
cvSVD(A, W, NULL, NULL, CV_SVD_MODIFY_A);

SVD 值存储在名为W的 Nx1 矩阵(在本例中为 IplImage)中。输入图像img在A中转换为 32 位。我们使用该CV_SVD_MODIFY_A标志使其更快并修改A中的值。其他选项留空 (NULL),但您可以根据需要提供参数。请检查这些 OpenCV 文档。

希望您能够从这个工作代码中找出您的 C++ 代码有什么问题。

于 2012-04-09T00:57:54.743 回答