テストする場合のコードは、MATLABは、その機能フリーマンチェーンコードを実行することはできませんが見つかりました:
fchcode境界と機能が正しく動作しています:
私たちはあなたの作業ディレクトリに以下の機能を追加する必要があります。
境界fchcode minmag codediff
コードは以下の通りであります:
関数B =境界(BW、CONN、DIR)
%境界は、オブジェクトの境界をトレースします。
%のB =境界(BW)は、バイナリ内のオブジェクトの外側境界をトレース
%イメージBW.B pは内のオブジェクトの数であるp_by_1セルアレイであり、
%のimage.Eachセルが含まれ、各行そのQ_by_2マトリックスを含み、
境界pixel.Qの%の行と列座標が境界の数であります
対応object.Object境界用%画素が中にトレースされ
%時計回り。
%
トレース場合%のB =境界(BW、CONN)を使用する接続を指定します
%boundaries.CONNはいずれであってもよいCONNための8または4。デフォルト値は8です。
%
%のB =境界(BW、CONN、DIR)は、トレースに使用される方向を指定します
boundaries.DIRは、いずれかの「CW」(時計回りのトレースの境界)でなければなりません%か
%「CCW」(反時計回りのトレース境界).IF DIRが境界を省略されています
時計回り方向%トレース。
in vivoでの関数nargin場合、<3%関数nargin定義されたユーザ定義関数、関数narginリターン
%変数の数の関数を呼び出すために使用されています。
DIR = 'CW';
終わり
関数nargin <2の場合
CONN = 8。
終わり
L = bwlabel(BW、CONN)は、%戻り値は、BWのタグ通信部を備え、サイズBWと、行列Lであります
%オブジェクトの数は、セルL.Initializeの最大値であります
%アレイの各セルは、最初0_by_2マトリックスを含むように(元包数组)B。
numObjects = MAX(L(:));%タグで行わLの最大値を検索し、最大値は、実際にはLに対応します
通信部の数%までが含まれます。
numObjects> 0であれば
B = {ゼロ(0,2)};%素子アレイパッケージは、一つの要素が含まれています。
B = repmat(B、numObjects、1);%Bは、* 1複製新しい設定B. numObjectsなり
他
B = {};
終わり
zeros.Thisと%パッドラベル行列は、私たちはboundary_followingループを書くことができます
画像のエッジをオフに行く気にせず%。
LP = padarray(L、[1 1]、0、 '両方')。
%のピクセルから私たちを取るために線形インデックスオフセットを計算し、その
%隣人。
M =サイズ(LP、1);%サイズ(Xは、1)行の数を返します。
場合connの== 8
%注文はN NE E SE S SW W NWです。
オフセット= [ - 1、M-1、M、M + 1,1、-M + 1、-M、-M-1]。
他
%注文はNES Wです。
オフセット= [ - 1、M、1、-M]。
終わり
%のnext_search_direction_lut画素から方向をtable.Givenルックアップであります
画素K + 1%のK、調べるときで開始する方向は何ですか
%ピクセルk + 1の近傍?
場合connの== 8
next_search_direction_lut = [8 8 2 2 4 4 6 6]。
他
next_search_direction_lut = [4 1 2 3]。
終わり
%のnext_direction_lutは、私たちは隣人を見て、ルックアップtable.Givenです
我々は、次を見てください隣人与えられた方向の%?
場合connの== 8
next_direction_lut = [1 2 3 4 5 6 7 8 1]。
他
next_direction_lut = [1 2 3 4]。
終わり
開始及び境界画素をマーキングするために使用される%値。
START = -1;
BOUNDARY = -2。
%境界画素を記録だけでなく、にスクラッチ領域を初期化します
%境界に従ってください。
スクラッチ=ゼロ(100,1)。
%候補が境界線の位置を開始して下さい。
[RR、CC =見つける((LP(2:エンド:1)> 0)&(LP(1:エンド2、:)== 0))。
RR = RR + 1。
長さ(RR):K = 1
R = RR(K);
C = CC(K);
(LP(R、C)> 0)&(LP(R-1、C)== 0)&のisEmpty(B {Lpの(R、C)})であれば
%私たちは、次のboundary.Computeその線形の開始を見つけました
%オフセット、それは境界のレコードは、それをマークし、初期化します
境界画素数の%カウンタ。
IDX =(C-1)*サイズ(LP、1)+ R。
これ= Lpの(IDX)。
スクラッチ(1)= IDX。
LP(IDX)= START。
numpixels = 1。
currentpixel = IDX。
initial_departure_direction = [];
= 0で行わ;
next_search_direction = 2。
〜行っている間
%次の境界画素を探します。
方向= next_search_direction。
found_next_pixel = 0;
K = 1:長さ(オフセット)
隣接= currentpixel +オフセット(方向)
Lpの(隣人)〜= 0の場合
%次の境界画素を発見しました。
もし(LP(currentpixel)== START)&...
isEmpty(initial_departure_direction)
%私たちは、開始から最初の出発を作っています
%ピクセル。
initial_departure_direction =方向。
ELSEIF(LP(currentpixel)== START)&...
(initial_departure_direction ==方向)
%私たちは道をたどるしようとしています。
私たちが行っていることを意味%。
= 1で行わ;
found_next_pixel = 1。
ブレーク;
終わり
%境界に沿って次のステップを取ります。
next_search_direction = ...
next_search_direction_lut(方向)。
found_next_pixel = 1。
numpixelsのnumpixels + = 1;
もしnumpixels>サイズ(スクラッチ、1)
%ダブルスクラッチスペース。
スクラッチ(2 *の大きさ(スクラッチ、1))= 0。
終わり
スクラッチ(numpixels)=隣接。
Lpの(隣人)〜= START場合
LP(隣接)= BOUNDARY。
終わり
currentpixel =隣人。
ブレーク;
終わり
方向= next_direction_lut(方向)。
終わり
〜found_next_pixel場合
%が次のネイバーが存在しない場合、オブジェクトはただ持っている必要があります
%つの画素。
numpixels = 2。
スクラッチ(2)=スクラッチ(1)。
= 1で行わ;
終わり
終わり
%座標をrow_columnとして保存するために線形インデックスに変換
%出力セルアレイ。
[行、COL = ind2sub(サイズ(LP)、スクラッチ(1:numpixels))。
B {} = [行1、COL-1]。
終わり
終わり
もしにstrcmp(DIR 'CCW')
長さ(B):K = 1
B {K} = B {K}(エンド:-1:1、:)。
終わり
終わり
関数c = fchcode(B、CONN、DIR)
%のFCHCODE境界のフリーマン・チェーン・コードを計算します。
%C = FCHCODE(B)の8連結フリーマンチェーンコードを計算します
2-Dの%セットはB、NP-によって-2配列に含まれる座標対。C
%は、以下のフィールドを持つ構造体です:
%
%のc.fcc =フリーマンチェーンコード(1-によって-NP)
%のc.diff =コードc.fcc(1-によって-NP)の第1の差分
%のc.mm c.fccから最小の大きさの整数=(1-によって-NP)
%のc.diffmm =コードc.mmの第1の差分(1-によって-NP)
コードは、(1×2)始まる%c.x0y0 =座標
%
%C = FCHCODE(B、CONN)は、上記と同じ出力を生成するが、
CONNで指定されたコードの接続性を持つ%。CONNは、のために8可能
%8に接続されたチェーンコード、またはCONNは、4連結のために4であることができます
%チェーンコード。CONN = 4を指定すると、入力のみ有効です
%の配列、Bは、値0、2、4との遷移を含み、6
%独占。
%
%C = FHCODE(B、CONN、DIR)は、上記と同様の出力を生成するが、
加えて、%は、所望のコード方向が指定されています。値
%DIRは指定できます
%
%Bにおける点列の順序と「同じ」と同じ。
%これがデフォルトです。
%
%「逆」出力に逆方向にコード
B.出発点における点の%の方向
各DIR用%は同じです。
%
%Bの要素が1ピクセルの厚さに対応すると仮定され、
%完全に接続され、境界を閉じました。Bは、重複を含めることはできません
%は、最初と最後の位置を除いて、座標対
%は、境界トレースプログラムの共通の特徴です。
%FREEMAN CHAINコード表現
%左の表は、8連結フリーマンチェーンコードを示し
%許容DELTAX、deltaY移動ペアに対応します。8-鎖であります
(1)= 4をconnの場合場合%は4本鎖に変換し; 及び(2)のみ
%トランジション0、2、4、6、8コードで起こります。ご了承ください
%2によって0、2、4、6 4コードを生成する分割。
%
%----------------------- ----------------
%DELTAX | deltaY移動| 8コードcorresp 4-コード
%----------------------- ----------------
%0 1 0 0
%-1 1 1
%-1 0 2 1
%-1 -1 3
%0 -1 4 2
%1 -1 5
%1 0 6 3
%1 7
%----------------------- ----------------
%
%式Z = 4 *(DELTAX + 2)+(deltaY移動+ 2)は、以下を与えます
上記の表の行1-8に対応%の配列:Z =
%11,7,6,5,9,13,14,15。これらの値は、へのインデックスとして使用することができます
%テーブル、チェーン・コードを計算速度を向上させることができます。ザ・
%上式は一意ではないが、それは最小に基づいています
%整数2の累乗である(4,2)。
%著作権2002年から2004年RCゴンザレス、REウッズ、&SL Eddins
MATLAB、プレンティス・ホール、2004を使用して%ディジタル画像処理
%の$リビジョン:1.6 $の$日:2003年11月21日午後二時34分49秒$
%予選。
もし関数nargin == 1
DIR = '同じ';
CONN = 8。
関数nargin == 2 ELSEIF
DIR = '同じ';
関数narginの== 3 ELSEIF
%ここでは何もします。
他
エラー(「入力の数が正しくありません。」)
終わり
[NP、NC] =サイズ(B)。
NP <NCの場合
エラー( 'BがサイズNP-によって-2でなければなりません。');
終わり
%などboundaries.mなどのプログラムを、トレーシングいくつかの境界、出力A
最初と最後の点の座標がされた%配列
% 同じ。この場合は、最後のポイントを排除します。
関数isequal IF(B(1、:)、B(NP、:))
NP = NP - 1。
B = B(1:NP :)。
終わり
%の式から単一のインデックスを使用してコードテーブルを作成
Zのための%は、上記で与えられました:
C(11)= 0。C(7)= 1。C(6)2 =。C(5)= 3。C(9)4 =。
C(13)= 5。C(14)= 6。C(15)= 7。
予選の%の終わり。
%処理を開始します。
X0 = B(1、1)。
Y0 = B(1、2)。
c.x0y0 = [X0、Y0]。
%座標が連続して編成されていることを確認してください:
%Bでの連続した点の間DELTAXとdeltaY移動を取得します。ザ・
%の最後の行は、Bの最初の行です。
= circshift(B、[-1,0])。
%DELは= - Bは、行が含まれているNR行2列の行列であります
B中の連続点間の%のDELTAXとdeltaY移動。二つ
マトリックスDELのk番目の行の%成分がDELTAXとdeltaY移動しています
点間の%(XK、YK)及び(XK + 1、YK + 1)。DELの最後の行
%は(XNR、YNR)及び(X1、Y1)との間DELTAXとdeltaY移動が含まれ、
%(すなわち、最後と最初の点の間のBで)。
; B - DELは=
%であればペアのどちらか(または両方)の成分の絶対値
%(DELTAX、deltaY移動)が曲線次に定義することによって、1よりも大きいです
%が壊れている(又は点が順序を外れている)、及びプログラム
%終了。
もしあれば(ABS(DEL(:, 1))> 1)| 任意(ABS(DEL(:、2))> 1)。
エラー(「入力曲線が破壊またはポイントが故障しているされています。」)
終わり
%、上述の式を使用して単一のインデックスベクトルを作成します。
Z = 4 *(DEL(:、1)+ 2)+(DEL(:、2)+ 2)。
%テーブルにマップするためにインデックスを使用してください。以下は、
%1行NPアレイに編成フリーマン8鎖コード、。
FCC = C(Z)。
%コードシーケンスの方向を逆にする必要があるかどうか確認してください。
(DIR、 '逆')strcmpの場合
FCC = coderev(FCC)。%関数coderevについては、以下を参照してください。
終わり
4接続が指定された%場合、すべてのコンポーネントことを確認し
FCCの%は、0、2、4、または6です。
場合connの== 4
ヴァル=見つける(FCC == 1 |のFCC == 3 | FCCの== 5 |のFCC == 7)。
isEmpty(val)であれば
FCC = fcc./2。
他
(「指定された4接続コードを満たすことができない。」)警告
終わり
終わり
構造出力の%フリーマンチェーンコード。
c.fcc = FCC;
%FCCの最初の差を求めます。
c.diff = codediff(FCC、CONN)。%関数codediffについては、以下を参照してください。
%最小の大きさの整数のコードを取得します。
c.mm = minmag(FCC)。%関数minmagについては、以下を参照してください。
%FCCの第1の差分を取得
c.diffmm = codediff(c.mm、CONN)。
関数z = minmag(C)
%MINMAGは、チェーンコードの最小の大きさの整数を検索します。
%Z = MINMAG(C)は、所定の最小の大きさの整数を見つけ
%の4-又は8連結フリーマンチェーンコード、C.は、コードがと仮定されます
%1行NP配列です。
%最小の大きさの整数分(C)で始まり、そこ
%は、複数のそのような値であってもよいです。それらすべてを検索し、
I =(C ==分(C))を見つけます。
それは分(C)で始まるようにそれぞれ左%およびシフト。
J = 0。
A =ゼロ(長さ(I)、長さ(c)参照)。
kについて= I;
J = J + 1。
(J、:) = circshift(C、[0 - (K-1)])。
終わり
%行列Aは、整数のためのすべての可能な候補が含まれています
%最小の大きさ。2列目以降では、succesively見つけます
%Aの各列の最小値は、候補の数が減少します
%A.これに右にさがす移動が反映されるように
J.の%要素長さ(J)= 1は、一つの候補が残ります。これは
%最小の大きさの整数。
[M、N] =サイズ(A)。
J =(1:M) '。
N:K = 2
D(1:M、1)[INFを=。
D(Jは、1)(J、K)を=。
=分((J、K))。
J =検索(D(:、1)==アミン)。
もし長さ(J)== 1
Z = A(J、:)。
リターン
終わり
終わり
関数d = codediff(FCC、CONN)
%CODEDIFFは、チェーンコードの最初の差を計算します。
%D = CODEDIFF(FCC)は、コード、FCCの第1の差分を計算します。ザ・
%のFCCは、円形配列として扱われるコードので、最後の要素
Dの%は、最後と最初の要素との間の差であります
%FCC。入力コードが1行NPベクターです。
%
%最初の差は、方向の数をカウントすることにより求められます
両者を分離する(反時計方向)%の変化
コードの%隣接する要素。
SR = circshift(FCC、[0、-1])。%シフト入力は1つの位置だけ左。
デルタ= SR - FCC;
D =デルタ;
I =(デルタ<0)を見つけます。
タイプ= CONN。
スイッチタイプ
ケース4%のコードは4に接続されています。
D(I)は、D(I)+ 4 =。
ケース8%のコードは8に接続されています。
D(I)は、D(I)+ 8 =。
終わり
より多くの機能を追加した後、テストコードをスムーズに実行することができます:
すべて閉じ、すべてクリア; CLC;
I = [1 1 1 1 1 1 0 1 0 1 0 1 0 1 1 1]。
G =境界(I、4);%目標トラック境界4が接続されています
C = fchcode(G {:}、4);%シーク方向フリーマンチェーンコード4
C
出力:
C =
X0Y0:[1]%のc.x0y0表示コード(1×2)の開始時に座標
FCCは:[0 0 0 3 3 3 2 2 1 1 2 1]%のc.fccフリーマンチェーンコード(1×n)で、サイズの境界点のセットを表す(N×2)
差分:[0 0 3 0 0 3 0 3 0 1 3 3]%のc.diff c.fcc第1差分コード(1×n)を
MM:[0 0 0 3 3 3 2 2 1 1 2 1]%のc.mmは、最小振幅の整数を表します。
diffmm:[0 0 3 0 0 3 0 3 0 1 3 3]%のc.diffmmオーダー差(1×n)を表すコードc.mmの