前面的视频是同一个方向转圈,如果到了一圈相反转,再相反转会怎样呢?
重新拍了一个视频,3圈(右--左--右),用前面的选片工具,选了86张图
接片效果图:
上下没有重合,如果前面有一张没有配好,后面的就全部不重合了。
先来看看一圈的效果:
去掉单图黑边
Mat myimread(string & n) { Mat im=imread(n); Mat roi2; im(Range(3, im.rows-6), Range(3, im.cols-6)).copyTo(roi2);//消除黑边 return roi2; }用这个函数代替imread:
加上左右融合:
void 融合(Mat & im,Mat &dst,Point2f p)//四边融合 { int w=100; //融合宽; int c=im.cols,r=im.rows; int c2=dst.cols,r2=dst.rows; float a;//权重 int x,y; for(int i=0;i<r;i++) { //左边 for(int j=0;j<w;j++) { x=p.x+j; y=p.y+i; if (dst.at<Vec3b>(y,x)[0]!=0 || dst.at<Vec3b>(y,x)[1]!=0 || dst.at<Vec3b>(y,x)[2]!=0) { a=1.0-(float)j/w;//权重 //原图和新图又叠加 dst.at<Vec3b>(y,x)[0]=a*dst.at<Vec3b>(y,x)[0] + (1.0-a)*im.at<Vec3b>(i,j)[0]; dst.at<Vec3b>(y,x)[1]=a*dst.at<Vec3b>(y,x)[1] + (1.0-a)*im.at<Vec3b>(i,j)[1]; dst.at<Vec3b>(y,x)[2]=a*dst.at<Vec3b>(y,x)[2] + (1.0-a)*im.at<Vec3b>(i,j)[2]; } else { //直接复制 dst.at<Vec3b>(y,x)[0]=im.at<Vec3b>(i,j)[0]; dst.at<Vec3b>(y,x)[1]=im.at<Vec3b>(i,j)[1]; dst.at<Vec3b>(y,x)[2]=im.at<Vec3b>(i,j)[2]; } } //右边 for(int j=c-w;j<c;j++) { x=p.x+j; y=p.y+i; if (dst.at<Vec3b>(y,x)[0]!=0 || dst.at<Vec3b>(y,x)[1]!=0 || dst.at<Vec3b>(y,x)[2]!=0) { a=(float)(j-(c-w))/w;//右边权重 dst.at<Vec3b>(y,x)[0]=a*dst.at<Vec3b>(y,x)[0] + (1.0-a)*im.at<Vec3b>(i,j)[0]; dst.at<Vec3b>(y,x)[1]=a*dst.at<Vec3b>(y,x)[1] + (1.0-a)*im.at<Vec3b>(i,j)[1]; dst.at<Vec3b>(y,x)[2]=a*dst.at<Vec3b>(y,x)[2] + (1.0-a)*im.at<Vec3b>(i,j)[2]; } else { dst.at<Vec3b>(y,x)[0]=im.at<Vec3b>(i,j)[0]; dst.at<Vec3b>(y,x)[1]=im.at<Vec3b>(i,j)[1]; dst.at<Vec3b>(y,x)[2]=im.at<Vec3b>(i,j)[2]; } } } Mat roi2(dst, Rect(p.x+w, p.y, im.cols-2*w, im.rows));//复制中间部分 im(Range(0, im.rows), Range(w, im.cols-w)).copyTo(roi2); }用这个函数代替复制部分:
效果好一点了,再把亮度校正下(匹配点):
//计算各图匹配点亮度比例 vector<float> 比_colors;//比_colors[i]表示第i个图像颜色和第一个图的比值 //亮度比值,第一个为1,其它相对于第一个 get亮度比率(image_colors,image_matches ,比_colors); //再把所有图像放到一个大图中(拼接) for (unsigned int i=0;i<position_da.size ();i++) { Mat im = myimread(image_names[i]);//读出一个图 //亮度调整 im/=比_colors[i];//按比值反向修正 int x=position_da[i].x-xmin; int y=position_da[i].y-ymin; //Mat roi2(stitch, Rect(x, y, im.cols, im.rows)); // im(Range(0, im.rows), Range(0, im.cols)).copyTo(roi2); //加融合+++++++++++++++++++++++++++ 融合(im,stitch,Point2f(x,y));//二边融合 }
最后二张图已经是第二圈的先把它去掉:
这样就好多了,再调整一下左右图高度,把它对齐:
前后对齐 { //再计算最小,最大边界 int xmin=0,xmax=0; int ixmin=1,ixmax=1;//最左和最右的位置 for (unsigned int i=1;i<position_da.size ();i++) { int ti,ta; ti=xmin;ta=xmax; xmin=(position_da[i].x<xmin)?position_da[i].x:xmin; xmax=(position_da[i].x>xmax)?position_da[i].x:xmax; if(ti!=xmin) ixmin=i; if(ta!=xmax) ixmax=i; } vector<DMatch> m; match_features1 (image_descriptor[ixmin], image_descriptor[ixmax], m); refineMatchesWithHomography( image_keypoints[ixmin], image_keypoints[ixmax],1.0, m ); cout<<"前后匹配数:"<<m.size ()<<endl; if(m.size ()>0){ //得到匹配点坐标 vector<Point2f> points1, points2; int src=ixmin; int dis=ixmax; get_match_points (image_keypoints[src], image_keypoints[dis] ,m, points1, points2); Point2f a = getOffset(points1,points2); cout << "前后两个相差:"<<a<< endl; //在大图的位置 //新的位置 position_s.x=position_da[src].x+a.x; position_s.y=position_da[src].y+a.y; //差值(新 - 老) position_s.x-=position_da[dis].x; position_s.y-=position_da[dis].y; cout << "位置差值:"<<position_s<< endl; //计算平均校正值 int p=dis-src-1;//中间数; float 平均x=position_s.x/p; float 平均y=position_s.y/p; for (unsigned int j=src+1;j<dis;j++) { //position_da[j].x+=平均x; position_da[j].y+=平均y; } } }
这是最终效果,虽然也不是很好,比前面已经好多了。