ここでは、質問を「パス最適化問題」としてモデル化することによる、問題の代替ソリューションを示します。単純な二値化と曲線化のソリューションよりも複雑ですが、実際にはより堅牢です。
非常に高いレベルから、この画像をグラフとして考える必要があります。
各画像ピクセルは、このグラフ上のノードです
各ノードは近隣ノードと呼ばれる他のノードに接続され、この接続定義は多くの場合、このグラフのトポロジと呼ばれます。
各ノードには重み(機能、コスト、エネルギー、または任意の名前)があり、このノードが探している最適な中心線にある可能性を反映しています。
この尤度をモデル化できる限り、「フリンジの中心線」を見つける問題は、グラフ上のローカル最適パスを見つける問題になります。これは、動的プログラミング、たとえばビタビアルゴリズムによって効果的に解決できます。
このアプローチを採用する長所は次のとおりです。
すべての結果は連続します(1つの中心線を分割する可能性のあるしきい値方法とは異なります)
そのようなグラフを作成するための多くの自由、さまざまな機能、およびグラフトポロジを選択できます。
パス最適化の意味で結果は最適です
ノイズがすべてのピクセルに均等に分配されている限り、それらの最適なパスは安定したままであるため、ソリューションはノイズに対してより堅牢になります。
上記のアイデアの簡単なデモを次に示します。事前の知識を使用して、可能な開始ノードと終了ノードを指定しないため、可能なすべての開始ノードを単純にデコードします。
ファジーエンドについては、考えられるすべての終了ノードの最適なパスを探しているという事実が原因です。その結果、暗い領域にある一部のノードでは、強調表示されたパスは依然としてそのローカル最適パスです。
ファジーパスの場合は、見つかった後にスムージングするか、生の強度の代わりにスムージングされた機能を使用できます。
開始ノードと終了ノードを変更することにより、部分的なパスを復元することができます。
これらの望ましくないローカル最適パスを除去することは難しくありません。ビタビ復号後のすべてのパスの可能性があるため、さまざまな事前知識を使用できます(たとえば、同じソースを共有する場合に必要な最適なパスは1つだけであることがわかります)。
詳細については、論文を参照してください。
Wu, Y.; Zha, S.; Cao, H.; Liu, D., & Natarajan, P. (2014, February). A Markov Chain Line Segmentation Method for Text Recognition. In IS&T/SPIE 26th Annual Symposium on Electronic Imaging (DRR), pp. 90210C-90210C.
上記のグラフを作成するために使用するPythonコードの短い部分を次に示します。
import cv2
import numpy as np
from matplotlib import pyplot
# define your image path
image_path = ;
# read in an image
img = cv2.imread( image_path, 0 );
rgb = cv2.imread( image_path, -1 );
# some feature to reflect how likely a node is in an optimal path
img = cv2.equalizeHist( img ); # equalization
img = img - img.mean(); # substract DC
img_pmax = img.max(); # get brightest intensity
img_nmin = img.min(); # get darkest intensity
# express our preknowledge
img[ img > 0 ] *= +1.0 / img_pmax;
img[ img = 1 :
prev_idx = vt_path[ -1 ].astype('int');
vt_path.append( path_buffer[ prev_idx, time ] );
time -= 1;
vt_path.reverse();
vt_path = np.asarray( vt_path ).T;
# plot found optimal paths for every 7 of them
pyplot.imshow( rgb, 'jet' ),
for row in range( 0, h, 7 ) :
pyplot.hold(True), pyplot.plot( vt_path[row,:], c=np.random.rand(3,1), lw = 2 );
pyplot.xlim( ( 0, w ) );
pyplot.ylim( ( h, 0 ) );