对自主标定的实现

//重新整理的比较清楚的opencv框架

#include "stdafx.h"

#include <cv.h>

#include <highgui.h>

#include <iostream>

using namespace std;

using namespace cv;

int _tmain(int argc, _TCHAR* argv[])

{

Mat lastWarpMatrix;Mat warpMatrix;

//读取数据

for (int i =2;i<=13;i++)//执行全部文件的遍历

{

char strimg[50];

sprintf(strimg,"image_%d.jpg",i);

cv::Mat src= cv::imread(strimg,0);

if (!src.data)

return 0;

// pyrDown(src,src);

Mat edge;Mat edgesobel;Mat edgetresh;

vector<std::vector<cv::Point>>contours;

threshold(src,edgetresh,22,255,cv::THRESH_BINARY);

imshow("edgetresh",edgetresh);

findContours(edgetresh,contours,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_NONE);

Mat result(src.size(),CV_8U,Scalar(255));

src.copyTo(result);

//寻找最大contours

int cmax = 0;

vector<vector<Point>>::const_iterator itc = contours.begin();

//在这种循环下面,最后一个就是最大的数据

while(itc!=contours.end())

{

if (itc->size()>cmax)

{

cmax = itc->size();

++itc;

}

else

{

itc = contours.erase(itc);

}

}

if (contours.size() <= 0)//如果没有数据

{

return 0;//error

}

drawContours(result,contours,-1,Scalar(255),1);

//获得最大外边距的点序列

std::vector<cv::Point> thiscount = contours[contours.size()-1];

Point lt =thiscount[0];Point ltEX  =thiscount[0];//前面为原始,后面为修正

Point rt =thiscount[0];Point rtEX  =thiscount[0];

Point ld =thiscount[0];Point ldEX  =thiscount[0];

Point rd =thiscount[0];Point rdEX  =thiscount[0];

for (int i = 0;i<thiscount.size();i++)

{

Point thispoint =thiscount[i];

//左上角,往往这个点也就是第一个点

if (thispoint.x<lt.x & thispoint.y<lt.y )

{

lt = thispoint;

}

//右上角

else if (thispoint.x>=rt.x & thispoint.y<5)

{

rt = thispoint;

}

//右下角 这里就是找最大的

else if (thispoint.x>rd.x /*& thispoint.y>100*/)

{

rd = thispoint;

}//左下角 这里就是找最小的

else if (thispoint.x<ld.x/* && thispoint.y >100*/)

{

ld = thispoint;

}

}

if ((ld.y == lt.y)|(rt.y==rd.y) )

{

printf("err in %d",i);

}

else

{

//修正,根据直线的斜率

ltEX.y = 0;rt.y = 0;rdEX.y = result.rows;ldEX.y = result.rows;

ltEX.x = (lt.x-ld.x)*lt.y/(ld.y-lt.y)+lt.x;

ldEX.x = ld.x-(ld.y-result.rows)*(lt.x-ld.x)/(lt.y-ld.y);

rtEX.x = rt.x+(rd.x-rt.x)*rt.y/(rt.y-rd.y)-13;//由于打光问题,进行修正。这样的修正是否可以将接口提取出来

rdEX.x = rd.x -(rt.x-rd.x)*(rd.y-result.rows)/(rt.y-rd.y);

cv::circle(result,ltEX,10,Scalar(255));

cv::circle(result,ldEX,10,Scalar(255));

cv::circle(result,rtEX,10,Scalar(255));

cv::circle(result,rdEX,10,Scalar(255));

printf("ltex %d %d\n",ltEX.x,ltEX.y);

printf("rtex %d %d\n",rtEX.x,rtEX.y);

printf("ldex %d %d\n",ldEX.x,ldEX.y);

printf("rdex %d %d\n",rdEX.x,rdEX.y);

if (ldEX.x<0)//问题出现

{

//当前错误,尝试lastwarp

if (lastWarpMatrix.rows == 0)

{

return 0 ;//TODO这个问题现在还没有解决。

}

else//存在lastwarp

{

lastWarpMatrix.copyTo(warpMatrix);

}

}

else

{

//warpperspective 透视矫正

Point2f src_vertices[4];

src_vertices[0] = ltEX;

src_vertices[1] = rtEX;

src_vertices[2] = ldEX;

src_vertices[3] = rdEX;

Point2f dst_vertices[4]; //边界略微留有黑边

dst_vertices[0] = Point(0+20, 0);

dst_vertices[1] = Point(result.cols-20,0);

dst_vertices[2] = Point(0+20,result.rows);

dst_vertices[3] = Point(result.cols-20,result.rows);

warpMatrix = getPerspectiveTransform(src_vertices, dst_vertices);

warpMatrix.copyTo(lastWarpMatrix);

}

cv::Mat rotated;

warpPerspective(src, rotated, warpMatrix, rotated.size(), INTER_LINEAR, BORDER_CONSTANT);

//cv::line(result,lt,ld,Scalar(255));cv::line(result,rt,rd,Scalar(255));

imshow("result",result);

imshow("rotated",rotated);

char rstr[50];

sprintf(rstr,"adjust%d.jpg",i);

imwrite(rstr,rotated);

}

cv::waitKey();

}

return 0;

}

对自主标定的实现,布布扣,bubuko.com

时间: 2024-12-15 23:37:48

对自主标定的实现的相关文章

示教编程技术,离线编程技术,自主编程技术,你精通哪种?

一.概述 当前机器人广泛应用于焊接.装配.搬运.喷漆及打磨等领域,任务的复杂程度不断增加,而用户对产品的质量.效率的追求越来越高.在这种形式下,机器人的编程方式.编程效率和质量显得越来越重要.降低编程的难度和工作量,提高编程效率,实现编程的自适应性,从而提高生产效率,是机器人编程技术发展的终极追求. 本文将就机器人编程技术的发展作一介绍,希望能给读者带来一些启发. 二.编程技术的发展及应用情况 对工业机器人来说,主要有三类编程方法:在线编程.离线编程以及自主编程三类.在当前机器人的应用中,手工示

基于OpenCV立体视觉标定和校正

这几天学习双目视觉标定,分别使用了两种工具:OpenCV和Matlab.Matlab的效果非常稳定,但是一开始OpenCV的效果很糟糕,要不是出现中断就是标定出来的结果数值很大.经过了几天的不断调试和更改,终于把OpenCV的立体视觉标定和校正的程序写出来了.立体标定时计算空间上的两台摄像机几何关系的过程,立体校正则是对个体图像进行纠正,保证这些图像可以从平面对准的两幅图像获得.程序的框架如下: 1.读取左右相机图片序列 双目相机的图片序列放在Demon的路径下,左右相机的图像的名字分别存放在两

基于EmguCV的摄像机标定及矫正

标签: EmguCV摄像头标定C# 2015-05-03 14:55 501人阅读 评论(6) 收藏 举报  分类: C# 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] 前言 之前用OpenCV做过摄像机标定及矫正,现在平台换了,改用C#,就用EmguCV做一下,其实就是OpenCV的C#版. 在EmguCV中有两类摄像机标定的类,一个是CvInvoke类,一个是CameraCalibration类,两种标定效果差不多,只不过CvInvoke涉及的函数大多都是指针类型的

在ROS中开始自主机器人仿真 - 1 概述

建立自主机器人是很难的,特别是在刚开始的时候. ROS 仿真有助于帮助我们从宏观上对机器人系统进行把握,帮助我们学习如何可以让机器人学会自己去适应环境. 明白机器人从测量和激光数据采集到转变为电机运动的过程. 机器人如何利用传感器进行感知, 找出好的路径, 应该执行什么样的命令. 这不是一套完整的自主机器人仿真的指导内容,但希望是一个好的开始. 所介绍的是小项目的一部分, 主要集中于如何开始自己的自主机器人仿真. 首先, 我们用ROS自带的turtlebot库,让机器人跑起来,这样我们有了直观的

闲话Linux系统安全(一)——自主访问控制(DAC)

我们口中的操作系统,一般指的是:一个操作系统核心+各种扩展应用程序.但从专业的角度来讲,操作系统就是那个核心(通常称之为内核),就是将底层硬件进行抽象和虚拟化,并向使用者提供各种功能接口的软件程序.这是一种非常特殊的软件程序,它的特殊之处就在于:操作系统是使用者运行其他应用程序的底层软件基础,也是硬件功能被集中管理和调用的统一接口.它向上层隐藏了硬件结构的丑陋和不易操作,使得使用者在使用计算机时变得更加简单:向下层屏蔽了底层硬件无法理解的使用者发出的复杂指令,将其翻译成二进制序列,使得硬件可以更

首次曝光!小米自主操作系统MIOS现身

双十一期间,小米手机无论是销量还是成交额都是位列第一,可谓是赚得钵满盆满.双十一狂欢的热浪还没完全退去,今天小米方面又有劲爆消息放出,这一次小米真的要玩一把大的了. 一.小米的mios系统首次曝光 据爆料,小米自去年4月份起就开始秘密研发自主智能机操作系统mios,预计将在下一代小米手机上使用.全新的mios基于Firefox OS深度定制的,但是经过小米的高度优化后,使用起来和目前的MIUI体验相差无几. 前段时间,小米曝光的399元超廉价新机很有可能就是搭载全新的mios系统,主打中国.印度

安卓kernel自主唤醒系统方法——设置alarm

我们知道alarm通常是上层设置后,kernel驱动里面将set time写入alarm寄存器,到达时间后trigger,殊不知kernel里面也可以自主设置alarm, 尤其是系统在休眠时驱动need do something时,这时睡前设置alarm后,alarm中断唤醒系统来执行. 之前写过一篇alarm文章,再想提下安卓kernel若要唤醒系统通常都是将中断注册作为唤醒源,由中断信号唤醒系统.同时在中断处理加入wake lock 机制来阻止系统休眠,直到任务完成后释放wake lock.

有序容器自主定义排序器

STL中的set和map是有序容器,使用时如果希望根据自己的需要来设定排序器,通常有一下两种方式. 1.如果容器中直接存储对象的话,那么我们可以在对象类中重载<即可,内置类型的话就不需要了,因为有默认的 2.如果存储的不是直接对象的话比如对象的指针(通常为智能指针),这个时候我们就要定义自己的比较器.而比较器的写法一般有两种. ->1.类内重载函数调用运算符的方法. ->2.以函数的方式提供比较器. 对于第一种方法是非常简单而且经常用的,这里不再赘述. 下面主要以一个简单的例子来介绍第二

双目相机标定以及立体测距原理及OpenCV实现

作者:dcrmg 单目相机标定的目标是获取相机的内参和外参,内参(1/dx,1/dy,Cx,Cy,f)表征了相机的内部结构参数,外参是相机的旋转矩阵R和平移向量t.内参中dx和dy是相机单个感光单元芯片的长度和宽度,是一个物理尺寸,有时候会有dx=dy,这时候感光单元是一个正方形.Cx和Cy分别代表相机感光芯片的中心点在x和y方向上可能存在的偏移,因为芯片在安装到相机模组上的时候,由于制造精度和组装工艺的影响,很难做到中心完全重合.f代表相机的焦距. 双目标定的第一步需要分别获取左右相机的内外参