有关图像校正的问题,请各位高手指点?(100分)

  • 主题发起人 主题发起人 wyb_star
  • 开始时间 开始时间
W

wyb_star

Unregistered / Unconfirmed
GUEST, unregistred user!
我用扫描仪档案资料,但有的图像倾斜,我打算在扫描的图像上加两个定位点来进行识别校正,如下图所示:
________________
|■ ■|
| |
| |
| |
| |
| |
| |
| |
| |
|_______________|

请各位高手指点,怎么样通过这种方式校正图像!
 
收藏!!!
 
我想通过两过定位点求出角度进行旋转校正, 但因水平有限,还肯请各位高手指点!
 
首先计算出扭曲的角度,也就是需要知道旋转多少度。
下面是围绕图象中心点进行任意角度的旋转,^_^

设定Image1.AutoSize :=True;

function TrimInt(i,Min,Max:Integer):Integer;
begin
if i>Max then Result:=Max
else if i<Min then Result:=Min
else Result:=i;
end;

function TMainForm.IntToByte(i:Integer):Byte;
begin
if i>255 then Result:=255
else if i<0 then Result:=0
else Result:=i;
end;

procedure GraphicRotate(var Src, Dst :TBitmap; cx, cy :Integer; Angle :Extended);
type
TFColor =record
b,g,r :Byte;
end;
var
Top,Bottom,Left,Right,eww,nsw,fx,fy,wx,wy :Extended;
cAngle,sAngle :Double;
xDiff,yDiff,ifx,ify,px,py,ix,iy,x,y,LL :Integer;
nw,ne,sw,se :TFColor;
P1,P2,P3 :PByteArray;
begin
Angle :=Angle;
Angle :=-Angle*Pi/180;
sAngle :=Sin(Angle);
cAngle :=Cos(Angle);
xDiff :=(Dst.Width-Src.Width)div 2;
yDiff :=(Dst.Height-Src.Height)div 2;
LL :=Dst.Height;
for y :=0 to Dst.Height-1 do
begin
P3 :=Dst.scanline[y];
py :=2*(y-cy)+1;
for x :=0 to Dst.Width-1 do
begin
px :=2*(x-cx)+1;
fx :=(((px*cAngle-py*sAngle)-1)/ 2+cx)-xDiff;
fy :=(((px*sAngle+py*cAngle)-1)/ 2+cy)-yDiff;
ifx :=Round(fx);
ify :=Round(fy);
if(ifx>-1) and (ifx<Src.Width)and (ify>-1) and (ify<Src.Height) then
begin
eww :=fx-ifx;
nsw :=fy-ify;
iy :=TrimInt(ify+1,0,Src.Height-1);
ix :=TrimInt(ifx+1,0,Src.Width-1);
P1 :=Src.scanline[ify];
P2 :=Src.scanline[iy];
nw.r :=P1[ifx*3];
nw.g :=P1[ifx*3+1];
nw.b :=P1[ifx*3+2];
ne.r :=P1[ix*3];
ne.g :=P1[ix*3+1];
ne.b :=P1[ix*3+2];
sw.r :=P2[ifx*3];
sw.g :=P2[ifx*3+1];
sw.b :=P2[ifx*3+2];
se.r :=P2[ix*3];
se.g :=P2[ix*3+1];
se.b:=P2[ix*3+2];
Top :=nw.b+eww*(ne.b-nw.b);
Bottom :=sw.b+eww*(se.b-sw.b);
P3[x*3+2] :=IntToByte(Round(Top+nsw*(Bottom-Top)));
Top :=nw.g+eww*(ne.g-nw.g);
Bottom :=sw.g+eww*(se.g-sw.g);
P3[x*3+1] :=IntToByte(Round(Top+nsw*(Bottom-Top)));
Top :=nw.r+eww*(ne.r-nw.r);
Bottom :=sw.r+eww*(se.r-sw.r);
P3[x*3] :=IntToByte(Round(Top+nsw*(Bottom-Top)));
end;
end;
end;
end;

procedure TForm1.Button1Click(Sender: TObject); //arbitrary degree rotation
var
Angle :Extended;
S: String;
Corners :array of TPoint;
x1,x2,y1,y2 :Integer;
SrcBmp,DstBmp :TBitmap;
Center :TPoint;

function MyRotate(var p :TPoint; ang :Extended):TPoint;
begin
Result.x :=Round((p.x*cos(DegToRad(ang)))-(p.y*sin(DegToRad(ang)))); //绕坐标原点旋转
Result.y :=Round((p.y*cos(DegToRad(ang)))+(p.x*sin(DegToRad(ang))));
end;

begin
S :='45';
Angle :=0.0;
SrcBmp :=TBitmap.Create;
SrcBmp.Assign(Form1.Image1.Picture.Bitmap);
if InputQuery('图象旋转','旋转角度(正值顺时针,负值逆时针):',S) then
Angle :=StrToFloat(S);
SetLength(Corners,4);
Corners[0].x :=-SrcBmp.Width div 2; // 0 1
Corners[0].y :=SrcBmp.Height div 2; // 2 3
Corners[1].x :=-Corners[0].x;
Corners[1].y :=Corners[0].y;
Corners[2].x :=Corners[0].x; //原坐标系角点坐标
Corners[2].y :=-Corners[0].y;
Corners[3].x :=-Corners[0].x;
Corners[3].y :=-Corners[0].y;
//BaseAngle :=BaseAngle+Angle; //BaseAngle 是基于原始位图的旋转
Corners[0] :=MyRotate(Corners[0],Angle{BaseAngle});
Corners[1] :=MyRotate(Corners[1],Angle{BaseAngle}); //新坐标系角点坐标
Corners[2] :=MyRotate(Corners[2],Angle{BaseAngle});
Corners[3] :=MyRotate(Corners[3],Angle{BaseAngle});
x1 :=MinIntValue([Corners[0].x,Corners[1].x,Corners[2].x,Corners[3].x]);
x2 :=MaxIntvalue([Corners[0].x,Corners[1].x,Corners[2].x,Corners[3].x]);
y1 :=MinIntValue([Corners[0].y,Corners[1].y,Corners[2].y,Corners[3].y]);
y2 :=MaxIntvalue([Corners[0].y,Corners[1].y,Corners[2].y,Corners[3].y]);
Corners :=nil;
DstBmp :=TBitmap.Create;
DstBmp.PixelFormat :=pf24bit;
DstBmp.Width :=x2-x1;
DstBmp.Height :=y2-y1;
Center.x :=DstBmp.Width div 2; //新的中心点
Center.y :=DstBmp.Height div 2;
GraphicRotate(SrcBmp,DstBmp,Center.x,Center.y,Angle{BaseAngle});
Form1.Image1.Picture.Bitmap.Assign(DstBmp);
SrcBmp.Free;
DstBmp.Free;
end
 
卷起千堆雪tyn:
TrimInt和IntToByte好象不是标准函数
 
卷兄:
你误会了,我要的不是图像旋转的算法,而是如何求出图像的倾斜的角度!
 
就是利用图像上的两个定位点求出图像的倾斜的角度!
 
TrimInt IntToByte 已经补上。
求出倾斜角度?
那就与水平两点形成的直线比较夹角好了。
倾斜图像的两个角点坐标知道吧,那就平移,与固定两点形成的直线不是有一个角度么?
这种东东也没法说清楚,[:)]
 
请指教!
 
如果你的两个点足够清楚,
1.先将图像二值化显示出那两个点
2.自己写一个算法识别出这两个点,(可参考区域填充算法,你自己变化一下,使用它能求出填充区域的重心和面积).
3.旋转图像
 
各位只要提供能找到两个定位点的坐标的算即可!
 
Tell me too!
 
多人接受答案了。
 
后退
顶部