直線検出のハフ変換プログラム(delphi)
ただいまdelphiで直線検出のハフ変換のプログラムを書いているのですが、コンパイルし、実行しようとするとスタックオーバーフローになってしまいます。
おそらく2次元配列のcounterの部分だと思うのですが、どなたか回避の仕方お分かりになるでしょうか?
ご存じの方いらっしゃいましたら教えて下さい。
下記にハフ変換の部分のコードを載せます。
他にも何か気付いた点ありましたらご指摘お願いいたします。
○直線検出のハフ変換○
var
i, j, k, n: Integer;
rx, ry: Integer;
clr: tcolor;
R: longint;
counter_max: Integer;
THETA_RESOLUTION, RHO_RESOLUTION, LNUMBER_MAX: Integer;
pai: Double;
theta, rho: Integer;
theta_max, rho_max, count: Integer;
theta_cut, rho_cut: Integer;
counter:array[0..1023,0..1999] of Integer; //直線検出のためのカウンタ
sn:array[0..1023] of Double; //sin
cs:array[0..1023] of Double; //cos
begin
THETA_RESOLUTION:=1024; //thetaの範囲は0から1023まで
RHO_RESOLUTION:=2000; //rhoの範囲は-1000から999まで
LNUMBER_MAX:=15; //検索する電線の数は15まで
pai:=PI / THETA_RESOLUTION; //π÷THETA_RESOLUTION
for i:=0 to 1023 do //sinとcosのテーブルを用意
begin
sn[i]:=Sin(pai*i);
cs[i]:=Cos(pai*i);
end;
//ハフ変換の実行//
for rx:=0 to 639 do
begin
for ry:=0 to 479 do
begin
clr:=image1.Canvas.Pixels[rx,ry];
R:=colortorgb(clr);
if(getrvalue(R)=0)and(getgvalue(R)=0)and(getbvalue(R)=0) then //黒である
for theta:=0 to 1023 do
begin
rho:=Trunc(rx*cs[theta]+ry*sn[theta]+0.5);
counter[theta,rho+1000]:=counter[theta,rho+1000]+1;
end;
end;
end;
//ハフ逆変換の実行//
for n:=0 to 14 do
begin
//counterが最大になるtheta_maxとrho_maxを求める//
counter_max:=0;
for theta:=0 to 1023 do
begin
for rho:=-RHO_RESOLUTION div 2 to RHO_RESOLUTION div 2-1 do
begin
if(counter[theta,rho+RHO_RESOLUTION div 2] > counter_max) then
begin
counter_max:=counter[theta,rho+RHO_RESOLUTION div 2];
theta_max:=theta;
rho_max:=rho;
count:=counter_max;
end;
end;
end;
//counter[theta_max,rho_max]の近傍を0にする//
for i:=-20 to 20 do
begin
for j:=-10 to 10 do
begin
theta_cut:=theta_max+i;
rho_cut:=rho_max+j;
if(theta_cut < 0) then
begin
theta_cut:=theta_cut+THETA_RESOLUTION;
rho_cut:=-rho_cut;
end
else if(theta_cut > THETA_RESOLUTION-1) then
begin
theta_cut:=theta_cut-THETA_RESOLUTION;
rho_cut:=-rho_cut;
end;
counter[theta_cut,rho_cut+RHO_RESOLUTION div 2]:=0; //削除する
end;
end;
//ハフ逆変換した結果の表示//
if(theta_max<>0) then //垂線の線を描く
begin
for rx:=0 to 639 do
begin
ry:=Trunc((rho_max-rx*cs[theta_max])/sn[theta_max]+0.5);
if(ry>=480)or(ry<0) then continue;
image1.Canvas.Pixels[rx,ry]:=RGB(255,0,0);
end;
end;
if(theta_max<>THETA_RESOLUTION div 2) then //水平の線を描く
begin
for ry:=0 to 479 do
begin
rx:=Trunc((rho_max-ry*sn[theta_max])/cs[theta_max]+0.5);
if(rx>=640)or(rx<0) then continue;
image1.Canvas.Pixels[rx,ry]:=RGB(255,0,0);
end;
end;
//直線を形成するピクセルが60個未満になったら表示しない//
if count<60 then break;
end;
end;
補足
reso for best picture quality, change resolution to っていうのはなんとなく解像度が違うからっていってるような気が するんですが、 やはりこれもスパイウェアなのでしょうか?