/****************倾斜校正子程序*****************/
//函数名称:IplImage *Rotate(IplImage *RowImage)
//功能:对每行数字进行倾斜校正
//入口参数:行图像RowImage
//出口参数:旋转后的图像RotateRow
/********************************************/
IplImage *Rotate(IplImage *RowImage)
{
//建立储存边缘检测结果图像canImage
// IplImage *canImage=cvCreateImage(CvSize(200,300),IPL_DEPTH_8U,1);
IplImage *canImage=cvCreateImage(cvGetSize(RowImage),IPL_DEPTH_8U,1);
//进行边缘检测
cvCanny(RowImage,canImage,30,200,3);
//进行hough变换
CvMemStorage *storage=cvCreateMemStorage();
CvSeq *lines=NULL;
lines=cvHoughLines2(canImage,storage,CV_HOUGH_STANDARD,1,CV_PI/180,20,0,0);
//统计与竖直夹角<30度的直线个数以及其夹角和
int numLine=0;
float sumAng=0.0;
for(int i=0;i<lines->total;i++)
{
float *line=(float *)cvGetSeqElem(lines,i);
float theta=line[1]; //获取角度 为弧度制
if(theta<30*CV_PI/180 || (CV_PI-theta)<30*CV_PI/180 )
{
numLine++;
sumAng=sumAng+theta;
}
}
//计算出平均倾斜角,anAng为角度制
float avAng=(sumAng/numLine)*180/CV_PI;
//获取二维旋转的仿射变换矩阵
CvPoint2D32f center;
center.x=float (RowImage->width/2.0);
center.y=float (RowImage->height/2.0);
float m[6];
CvMat M = cvMat( 2, 3, CV_32F, m );
cv2DRotationMatrix( center,avAng,1, &M);
//建立输出图像RotateRow
double a=sin(sumAng/numLine);
double b=cos(sumAng/numLine);
int width_rotate=int (RowImage->height*fabs(a)+RowImage->width*fabs(b));
int height_rotate=int (RowImage->width*fabs(a)+RowImage->height*fabs(b));
IplImage *RotateRow=cvCreateImage(cvSize(width_rotate,height_rotate),IPL_DEPTH_8U,1);
//变换图像,并用黑色填充其余值
m[2]+=(width_rotate-RowImage->width)/2;
m[5]+=(height_rotate-RowImage->height)/2;
cvWarpAffine(RowImage,RotateRow, &M,CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS,cvScalarAll(0));
//释放
cvReleaseImage(&canImage);
cvReleaseMemStorage(&storage);
return RotateRow;
}
int main(int argc, char *argv[])
{
// QCoreApplication a(argc, argv);
Mat imgMat = imread("20160802.jpeg");//const String* filename);
// Mat imgMat = imread("DSCN6533.png");//const String* filename);
if(imgMat.empty())return -1; //是否加载成功
if(!imgMat.data)return -1;//判断是否有数据
// IplImage pImg= IplImage(imgMat);
IplImage *pImg = cvLoadImage("20160802.jpeg");
IplImage *tImg =Rotate(pImg);
// IplImage* img = cvCreateImage(cvGetSize(mat),8,1);
// cvGetImage(matI,img);
cvSaveImage("rice1.png",tImg);
//建立储存边缘检测结果图像canImage
return 0;//a.exec();
}
上述代码会报错:
Assertion failed (src.type() == dst.type()) in cvWarpAffine, file /home/lbg/softs/opencv-3.0.0/modules/imgproc/src/imgwarp.cpp, line 6369
terminate called after throwing an instance of 'cv::Exception'
what(): /home/lbg/softs/opencv-3.0.0/modules/imgproc/src/imgwarp.cpp:6369: error: (-215) src.type() == dst.type() in function cvWarpAffine
下面是python的:
__author__
= 'Administrator' |
|
from argparseimport ArgumentParser |
|
FILENAME=
"1.150000001.png"; |
|
#srcImgOrg : the source image |
|
#srcImgGray : the source image with gray scale |
|
defcalcRotAngle(srcImgOrg,srcImgGray): |
|
opWidth
= cv.getOptimalDFTSize(srcImgGray.shape[1]) |
|
opHeight
= cv.getOptimalDFTSize(srcImgGray.shape[0]) |
|
padded
= cv.copyMakeBorder(srcImgGray, 0, opWidth
- srcImgGray.shape[1] , 0, opHeight- srcImgGray.shape[0], cv.BORDER_CONSTANT); |
|
plane
= np.zeros(padded.shape,dtype=np.float32) |
|
#Merge into a double-channel image |
|
comImg
= cv.merge(planes) |
|
planes[0]= cv.magnitude(planes[0], planes[1]); |
|
magMat
+= np.ones(magMat.shape) |
|
cx
= magMat.shape[1] /
2; |
|
magMat2
= np.hstack((c1,c2)) |
|
cv.normalize(magMat2, magMat,0,
1,cv.NORM_MINMAX); |
|
magMat
= cv.resize(magMat,(magMat.shape[0]
/ 2,magMat.shape[1]/2)) |
|
magMat
= cv.threshold(magMat,GRAY_THRESH,255,cv.THRESH_BINARY)[1].astype(np.uint8) |
|
lines
= cv.HoughLines(magMat,1,np.pi/180,HOUGH_VOTE); |
|
#cv.imshow("mag_binary", magMat); |
|
#lineImg = np.ones(magMat.shape,dtype=np.uint8) |
|
if lines!=
None andlen(lines)
!= 0: |
|
if (theta< (np.pi/4. ))or (theta
> (3.*np.pi/4.0)): |
|
print'Vertical line , rho :
%f , theta : %f'%(rho,theta) |
|
pt1
= (int(rho/np.cos(theta)),0) |
|
pt2
= (int((rho-magMat.shape[0]*np.sin(theta))/np.cos(theta)),magMat.shape[0]) |
|
#cv.line( lineImg, pt1, pt2, (255)) |
|
print'Horiz line , rho :
%f , theta : %f'%(rho,theta) |
|
pt1
= (0,int(rho/np.sin(theta))) |
|
pt2
= (magMat.shape[1], int((rho-magMat.shape[1]*np.cos(theta))/np.sin(theta))) |
|
#cv.line(lineImg, pt1, pt2, (255), 1) |
|
angle
= theta + np.pi /
2 |
|
#cv.imshow('lineImg',lineImg) |
|
#Calculate the rotation angel |
|
#The image has to be square, |
|
#so that the rotation angel can be calculate right |
|
alpha
= float(srcImgOrg.shape[1])/
float(srcImgOrg.shape[0]) |
|
angleT
= srcImgOrg.shape[1] * np.tan(angle)/ srcImgOrg.shape[0]; |
|
angleD
= np.arctan(angleT) * 180/ np.pi; |
|
angleD
= angle * 180
/ np.pi |
|
print'angleD :
%f'% angleD |
|
defrotImage(srcImgOrg,angleD): |
|
centerPnt
= (srcImgOrg.shape[1] /2,srcImgOrg.shape[0]
/ 2) |
|
rotMat
= cv.getRotationMatrix2D(centerPnt,angleD,scale=1.); |
|
resultImg
= cv.warpAffine(srcImgOrg,rotMat,(size[1],size[0])); |
|
#cv.imshow('srcImgOrg',srcImgOrg); |
|
#resultImg = cv.resize(resultImg,(resultImg.shape[0] / 2,resultImg.shape[1]/2)) |
|
#cv.imshow("resultImg",resultImg); |
|
fileParts
= fileName.split('.') |
|
fileParts[-2]= fileParts[-2]+
'-r' |
|
file=
'.'.join(fileParts) |
|
print"file name :
%s"%
file |
|
ret
= cv.imwrite(file,resultImg) |
|
defhandleImage(fileName): |
|
srcImgOrg
= cv.imread(fileName) |
|
srcImgGray
= cv.imread(fileName,cv.IMREAD_GRAYSCALE).astype(np.float32); |
|
angle
= calcRotAngle(srcImgOrg,srcImgGray) |
|
rotImage(srcImgOrg,angle) |
|
p
= ArgumentParser(usage='it is usage tip',description='this
is a usage tip') |
|
p.add_argument('--file',default="./",help='input
file name') |
|
if__name__
== '__main__': |
|
cv.waitKey(
0)
参考:https://github.com/lyzh1688/SlantCorrection
opencv图像校正(摄像头校正)
需要事先标定:
http://download.youkuaiyun.com/download/hs5530hs/9046567
需要事先标定:
http://blog.youkuaiyun.com/zht9961020/article/details/7036786