Image processing OpenCV-图像拼接
我使用以下代码来缝合输入图像。为了一个未知的世界 输出结果是垃圾的原因! 单应矩阵似乎是错误的(或受到错误的影响) 因为变换后的图像就像一颗“被利用的星星”! 我已经评论了我认为是问题根源的部分 但我无法意识到这一点。 任何帮助或观点都将受到感谢 祝你今天愉快, 阿里Image processing OpenCV-图像拼接,image-processing,opencv,image-stitching,Image Processing,Opencv,Image Stitching,我使用以下代码来缝合输入图像。为了一个未知的世界 输出结果是垃圾的原因! 单应矩阵似乎是错误的(或受到错误的影响) 因为变换后的图像就像一颗“被利用的星星”! 我已经评论了我认为是问题根源的部分 但我无法意识到这一点。 任何帮助或观点都将受到感谢 祝你今天愉快, 阿里 无效缝合2图像(IplImage*mImage1,IplImage*mImage2) { //将输入图像转换为灰色 IplImage*gray1=cvCreateImage(cvSize(mImage1->宽度,mImage1-
无效缝合2图像(IplImage*mImage1,IplImage*mImage2)
{
//将输入图像转换为灰色
IplImage*gray1=cvCreateImage(cvSize(mImage1->宽度,mImage1->高度),8,1);
CVTColor(图像1,灰色1,CV_bgr2灰色);
IplImage*gray2=cvCreateImage(cvSize(mImage2->宽度,mImage2->高度),8,1);
CVT颜色(mImage2,灰色2,CV_bgr2灰色);
//将灰色图像转换为Mat
Mat img1(灰色1);
Mat-img2(灰色2);
//检测第一张图像中的快速关键点和简要特征
快速特征检测器(50);
简介描述符牵引器描述符牵引器;
BruteForceMatcher描述符格式化程序;
向量关键点1;
检测器。检测(img1,关键点1);
Mat描述符1;
描述符Extractor.compute(img1,关键点1,描述符1);
/*检测第二张图像中的快速关键点和简要特征*/
向量关键点2;
检测器。检测(img1,关键点S2);
Mat描述符2;
descriptorExtractor.compute(img2,keypoints2,descriptors2);
向量匹配;
描述符匹配(描述符1,描述符2,匹配);
如果(匹配.size()==0)
返回;
向量点1,点2;
对于(size_t q=0;q宽度*2,mImage2->高度),8,3);
cvZero(结果);
//复制结果图像中的第二个图像
cvSetImageROI(结果,cvRect(mImage2->width,0,mImage2->width,mImage2->height));
cvCopy(图像2,结果);
cvi(结果);
//创建扭曲图像
IplImage*warpImage=cvCloneImage(结果);
cvZero(扭曲图像);
/**************************这里有什么问题吗?******************/
//求单应矩阵
Mat H=findHomography(Mat(点S1)、Mat(点S2)、8、3.0);
CvMat HH=H;//此行转换是否正确?
//变换扭曲图像
cvWarpPerspective(mImage1、warpImage和HH);
//调和
混合(结果、图像);
/*******************************************************************************/
cvReleaseImage(&gray1);
cvReleaseImage(&gray2);
cvReleaseImage(&warpImage);
}
我建议您按以下顺序尝试:
1) 使用CV_RANSAC选项进行单应性。提及
2) 尝试其他描述符,尤其是使用OpenCV发布的SIFT或SURF。对于某些图像,快速或简短的描述符没有足够的辨别力。编辑(8月12日):基于简介的ORB描述符非常好而且快速
3) 尝试查看单应矩阵(在调试模式下单步执行或打印),看看它是否一致
4) 如果上面没有给你一个线索,试着看看形成的匹配。它是否将一幅图像中的一个点与另一幅图像中的多个点相匹配?如果是这样,问题应该再次出现在描述符或检测器上
我的直觉是,这是描述符(所以1)或2)应该解决的问题。你的单应性可能是基于错误的匹配计算出来的,因此表示错误的匹配。 我建议通过对矩阵行之间的相互依赖性进行额外的检查来确定矩阵的路径 您可以使用以下代码:
bool cvExtCheckTransformValid(const Mat& T){
// Check the shape of the matrix
if (T.empty())
return false;
if (T.rows != 3)
return false;
if (T.cols != 3)
return false;
// Check for linear dependency.
Mat tmp;
T.row(0).copyTo(tmp);
tmp /= T.row(1);
Scalar mean;
Scalar stddev;
meanStdDev(tmp,mean,stddev);
double X = abs(stddev[0]/mean[0]);
printf("std of H:%g\n",X);
if (X < 0.8)
return false;
return true;
}
bool cvExtCheckTransformValid(常量材料和测试){
//检查矩阵的形状
if(T.empty())
返回false;
如果(T.rows!=3)
返回false;
如果(T.cols!=3)
返回false;
//检查线性相关性。
Mat-tmp;
T.row(0).copyTo(tmp);
tmp/=T.row(1);
标量平均值;
标量stddev;
平均标准差(tmp,平均标准差);
双X=abs(标准差[0]/平均值[0]);
printf(“H的标准值:%g\n”,X);
如果(X<0.8)
返回false;
返回true;
}
在BruteForceMatcher中也切换到汉明距离,而不是L1距离。简要描述符应该使用汉明距离进行比较
bool cvExtCheckTransformValid(const Mat& T){
// Check the shape of the matrix
if (T.empty())
return false;
if (T.rows != 3)
return false;
if (T.cols != 3)
return false;
// Check for linear dependency.
Mat tmp;
T.row(0).copyTo(tmp);
tmp /= T.row(1);
Scalar mean;
Scalar stddev;
meanStdDev(tmp,mean,stddev);
double X = abs(stddev[0]/mean[0]);
printf("std of H:%g\n",X);
if (X < 0.8)
return false;
return true;
}