//重新整理的比较清楚的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;
}
目前方向:图像拼接融合、图像识别 联系方式:jsxyhelu@foxmail.com