分块仿射变换

本文介绍了一种使用OpenCV实现的图像处理方法,通过光流法追踪图像特征点并利用仿射变换进行图像校正。具体步骤包括从原始图像中提取特征点,计算这些特征点在后续帧中的位置变化,并根据变化情况调整图像。此外,还介绍了如何筛选有效的特征点以提高精度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include "stdafx.h"  
#include <opencv2/video/video.hpp>  
#include <opencv2/highgui/highgui.hpp>  
#include <opencv2/imgproc/imgproc.hpp>  
#include <opencv2/core/core.hpp>  
#include <fstream>    
#include <iostream>  
#include <cstdio>  
#include "features2d/features2d.hpp"  
using namespace std;  
using namespace cv;  
  
vector<Point2f> features; // 检测的特征  
  
int maxCount = 500; // 检测的最大特征数  
double qLevel = 0.01;   // 特征检测的等级  
double minDist = 10.0;  // 两特征点之间的最小距离  
vector<uchar> status; // 跟踪特征的状态,特征的流发现为1,否则为0  
vector<float> err;  
void on_mouse( int event, int x, int y, int flags, void* ustc);  
bool acceptTrackedPoint(int i);  
void main(){  
    Mat output,origin;  
    Mat image=imread("G:\\6.jpg",0);  
    Mat image2=imread("G:\\10.jpg",0);
	Mat result=imread("G:\\6.jpg",0);  
    Mat resutl=imread("G:\\10.jpg",0);
    origin=imread("G:\\6.jpg",1);  
    output=imread("G:\\10.jpg",1);  
	int m=1;
      
	//Mat imageROI1=image(Rect(0,90,160,45));
	//Mat imageROI2=image2(Rect(0,90,160,45));

	Mat imageROI1[4][8];
	Mat imageROI2[4][8];
	//Mat resultROI[4][8];
	Mat result1ROI[4][8];
	for(int k=0;k<4;k++)//行
		for(int t=0;t<8;t++){//列
		imageROI1[k][t]=image(Rect(80*t,45*k,80,45));
		imageROI2[k][t]=image2(Rect(80*t,45*k,80,45));
	
		result1ROI[k][t]=resutl(Rect(80*t,45*k,80,45));
		
		Mat warp_mat( 2, 3, CV_32FC1 );
		Mat warp_dst;
		vector<Point2f> points[2];    // point0为特征点的原来位置,point1为特征点的新位置
		/**
		 * 提取像素点
		 */
		for(int j=0;j<imageROI1[k][t].rows;j+=15)//列
			for(int i=0;i<imageROI1[k][t].cols;i+=15)//行
			{
				points[0].push_back(Point2f(i,j));
			}

		
		
		//检测第二帧对应特征点  
        calcOpticalFlowPyrLK(imageROI1[k][t], imageROI2[k][t], points[0], points[1], status, err);
		
		//根据两帧之间特征点矢量长度去掉一些不好的特征点  
		
		int kk = 0;  
		for (size_t i=0; i<points[1].size(); i++)  
		{  
			if (acceptTrackedPoint(i)&&((abs(points[0][i].x - points[1][i].x) + abs(points[0][i].y - points[1][i].y)))<20)  
			{  
				points[0][kk]=points[0][i];  
				points[1][kk++] = points[1][i];  
			}  
		}  
		
		points[1].resize(kk);  
		points[0].resize(kk);

		//cout<<m++<<endl;
	//	cout<<points[0]<<endl;
	//	cout<<points[1]<<endl;
		if(points[0].size()>=3&&points[1].size()>+3){
			cout<<points[0].size()<<endl;
			cout<<points[1].size()<<endl;
		warp_mat=estimateRigidTransform(points[1],points[0],1);//求出仿射变换矩阵
		
		warpAffine( imageROI2[k][t], warp_dst, warp_mat, warp_dst.size() );//进行仿射变换
	//	absdiff(imageROI1[k][t],warp_dst,result);//进行差分运算
	//	absdiff(imageROI1[k][t],imageROI2[k][t],result1ROI[k][t]);//进行差分运算
		warp_dst.copyTo(imageROI2[k][t]);
		}
		
	}
	
	
	 
      
  
/*for (size_t i=0; i<points[1].size(); i++)  
    {  
		
        line( imageROI2[k][t], points[0][i], points[1][i], Scalar(0, 255, 255));  
        circle( imageROI2[k][t], points[0][i], 2, Scalar(255, 0, 0), -1);  
        circle( imageROI2[k][t], points[1][i], 2, Scalar(0, 255, 0), -1);  
		cout<<(abs(points[0][i].x - points[1][i].x) + abs(points[0][i].y - points[1][i].y))<<endl;
    } */ 
//
//
//    for (size_t i=0; i<points[0].size(); i++)  
//    {  
//        circle(origin, points[0][i], 2, Scalar(255, 0, 0), -1);   
//    } 
//
//
//	/*画网格线*/
	line(image2, Point(0,45), Point(640,45), Scalar(255, 255, 0));  
	line(image2, Point(0,90), Point(640,90), Scalar(255, 255, 0));
	line(image2, Point(0,135), Point(640,135), Scalar(255, 255, 0));
	for(int i=0;i<640;i+=80)
	{
		line(image2, Point(i,0), Point(i,180), Scalar(255, 255, 0));
	}




  /*  imshow("origin1",origin);  
    imshow("output1",output);  
    cvSetMouseCallback( "output", on_mouse, 0 );     
    cvSetMouseCallback( "origin", on_mouse, 0 );     
  */
  
    
   
	  
   
   
//	imshow("original",imageROI1);
//	imshow("output",imageROI2);
 //   imshow("仿射变换",warp_dst);;   
    
    imshow("仿射帧间差",image);  
    imshow("直接帧间差1",image2);  
    waitKey(0);  
//  
}  
bool acceptTrackedPoint(int i)  
{  
   // return status[i] && ((abs(points[0][i].x - points[1][i].x) + abs(points[0][i].y - points[1][i].y)) <50)&& ((abs(points[0][i].x - points[1][i].x) + abs(points[0][i].y - points[1][i].y)) > 0);  
	 return status[i] ;  
}  
void on_mouse( int event, int x, int y, int flags, void* ustc)      
{      
    CvFont font;      
    cvInitFont(&font, CV_FONT_HERSHEY_SIMPLEX, 0.5, 0.5, 0, 1, CV_AA);      
              
    if( event == CV_EVENT_LBUTTONDOWN )      
    {      
        CvPoint pt = cvPoint(x,y);      
        char temp[16];      
        sprintf(temp,"(%d,%d)",pt.x,pt.y);      
        cout<<temp<<endl;    
    }       
}   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值