概要

大きな画像の一部が切り出された複数の画像から、元の画像内での座標を取得する機会がありました。本記事では、そのための方法についての備忘録をまとめます。

OpenCV の SIFT (Scale-Invariant Feature Transform) を用いて、テンプレート画像と元の画像を特徴点マッチングし、アフィン変換を推定して座標を取得する方法を紹介します。

実装

必要なライブラリ

pipinstallopencv-pythonnumpytqdm

Pythonコード

以下のコードでは、指定した大きな画像 (image_path) に対して、テンプレート画像 (templates_dir 内の PNG 画像) を SIFT でマッチングし、元の画像内の座標を取得します。

iiffi#d#d#d#d#d#dmmrrmeeeeeeppoopffffffoommorrrliirermmgresdMrdhrtcrm#itd#sbk#if#cpttgttomfexeaaoesrs_er,erveamesifpfovrlqagtttttottctataca2tigmtSf1r2icnododiuruccdui__fuwwtn.unp_It=,d.nvubms_=mprarhh_rmppfr__spr(=liFeprttikigi#Mi#b#xbcit2migrncn_emnattinm=pfoni_mT=cdsreeefpfof_fe,avm(piimcitfsatssnatolmlpgve1itmm2oass2wfymmavini_detgeeMttsrytaoac2snuppt,ddgfMtye.r"ppg2stmfea=co_==,_cemlrgat=v.1itrllecec_opcf_pc_,_piaooe.(getthoaahm=eiaedh2Bs(n_modsomoroiarodnutsrr_iNfaeumedfnn_fepdnn__sc.F="p=pne2nadinnfins_atettgmo"tcras_fppfdln_espivSMNaltstt_ntefntt,mT(nrrnutetmi..=i__ppsfam=2Iaeotli2iicmtiitieeopgtaeerosc=anffnrs.t(ota.&Ftxnhoinsnha(n=n(n=_xulqya:er(htellceehfsirhggiTcteasu=uetfuefu=ttod(ds.de[c_oovcalmm,elmB_hr:ideNesc"ee"ed=(pbmp((dermhtaa2tpo=ae_orFcean_Neohsiroduapies.ertt.aeagdtgbeMrrcioxn=etsacssttamt1kfsa33entce_er(aae(ttmntesiwv.t_htae,non22sg3v,pmatdtac_qaer:mmN_2p_p:)hgcnris((tl22tpye(ctvfdg:aaiaom.aia:,etdMff[[ie(.[sl(mihe2emectstnabtmt{:,Aeamokkm([tnaipme(.a(_tceetohghocnst,lrppai[rptmlar)Nttg_hN_:cu.,,uv{dd2cem21tm0a.eaagOuerf_oahnst2peC,hnn([[ea,nisgteRrmaefnfedpbdp.ato((kmmAgsn_ee_MepyaeefdilasuItemmdigp..fe0ftd_sp_sl(ta:i:_nisttMhcpaeno1tqf,]o3ip_aL(_tut:nrgte__R}tutso,rui,r2radt2iperue{eRe_ipE"otc1mdaenMm(,tih,mamer{_tcexnmaA)reh,a_kire_[(thr)g"tpsettetctagtD)(etmpnyPawnro))c,)hl(sermat(m)h_:irdca2IIaf,paurs_t(mapn(oe}Gm,eht,ddrf.ntos)pedpnlgbs,"Rasecxxti0aspsi:amels_le.)Agr2shg]]in]rfusftps_fpesp(Yea,eo..ae,rotCthl1poa(taxS,tisoppl,ar_h)),,artd_t,Cikf)dtt2[ympetmhsdhANo=_Dtw(eacsdh(}ts.yLo_2m>mff(e,[dtkie}k"_tbEnt).=aoosmr_h=fs"p)i)a-)eedtrrrphep)Ft2)1ms)simccl]ct:a),,ge1tsihmm__,tsl,n0=tneps_)sbka)0a_siith[p]efpMm,.nm)nnsa0t,))2_e7ca:,p,s,a(c,etgge]iftvcood)h)sgfe2m<hoos:],Coim.ieddt]lonpFnrs___)ModelO_ammp_s_,_NmteaataempTailtts#fdata_toscc,f=tetHc_ehhiTcmhEhteemnrhp)ReeNsseeuel)Ssso]]t)es.[H=tn))h[,)s0E4e..o0h]Y)rrd]ca_:ee=opSnsscleI.hhv#o)Mdaa2rPipp.=LseeR(Et((A0Xa--N,,n11Sc,,A01eC,,]11,,,2(r5022a5,))n)s,0a,ctRh2ei5pc5rk)on,jeTs2hs)r=e2s)hold=5.0)

実行

#if_#ITOmnMEUaaAMTimGPPneELU(__ATI_PT_MAEPA=TSAG=H_TEDH_"=IP_R=A_"Tm/="Hax/,ix"xnxxT_xxE_dx/M"exmP:f/aLa*tAu.cTlphEtn_S.gr_j"eDpsIguR"l,t.OjUpTgP"UT_PATH)

まとめ

本記事では、SIFT を用いた特徴点マッチング によって、部分画像が元画像のどこに位置するかを推定し、アフィン変換 で位置を特定する方法を紹介しました。

✅ 特徴点の抽出には SIFT を使用(OpenCV 4.4 以降は自由に使用可能)

✅ BFMatcher で特徴点をマッチングし、RANSAC でノイズを除去

✅ アフィン変換で座標を推定し、矩形で元画像に描画

✅ 結果画像を保存し、どの部分画像がどこにあるかを可視化

この方法を活用すれば、古地図の部分画像の位置特定、OCR の領域検出、画像比較などにも応用できます。

📌 今後の課題

  • 画像が回転している場合の補正

  • SIFT より高速なアルゴリズムの検討(ORB, AKAZE など)

  • 処理速度の最適化(特徴点のフィルタリング)

以上、不完全な点もあるかもしれませんが、参考になりましたら幸いです。 📝