OpenCV:cvFindContours 正常に出来た

2017-07-30 :  PCクリニック
以前(2017-07-21)の記事「GSL Shell/OpenCV 学習:cvFitEllipse2」以来、
原因が分からなかった、cvFindContoursの結果不正。

遂に、原因が判明した。

改めて、当該関数の定義を見直すと:
int cvFindContours( CvArr* image, CvMemStorage* storage, CvSeq** first_contour,
int header_size=sizeof(CvContour), int mode=CV_RETR_LIST,
int method=CV_CHAIN_APPROX_SIMPLE, CvPoint offset=cvPoint(0,0) );
とある。
ここで、最後の7番目の引数に関しては、
  offset - Optional offset by which every contour point is shifted. ・・・
と(Optional)とあるので、省略していた。
しかし、5番目、6番目はデフォルトとかを指定していた。

つまり、7番目もデフォルト値を指定すべきだった。

と云うことで、完成したコード:
---- GSL Shell コード
cv2 = require'cv2'
ffi.cdef[[
/****************************/
/* 不足分の関数宣言を記述 */
/****************************/
]]
---- ・・・・・
img = cv2.cvLoadImageM( 'Threshold.tif', 0 ) -- CV_8UC1 入力
xx, yy = img.xx, img.yy

img2=cv2.cvCreateMat(yy,xx,16) -- CV_8UC3 領域
cv2.cvCvtColor( img, img2, 8 ) -- CV_GRAY2BGR BWからcolor

storage = cv2.cvCreateMemStorage( 0 )

contours=ffi.new('CvSeq*[1]'); P0=ffi.new('CvPoint', 0, 0 )

r = cv2.cvFindContours( img, storage, contours, 88, 3, 2, P0 )

it=ffi.new('CvTreeNodeIterator[1]')
cv2.cvInitTreeNodeIterator( it, contours[0], 3 )

while true do
cnt = ffi.cast( 'CvSeq*', cv2.cvNextTreeNode( it ) )
if cnt == nil then break end

ell = cv2.cvFitEllipse2( cnt )

P1=ffi.new('CvPoint'); S1=ffi.new('CvSize')
P1.x, P1.y = ell.x+0.5, ell.y+0.5
S1.xx, S1.yy = ell.xx/2+0.5, ell.yy/2+0.5
Sc1=ffi.new('CvScalar', 255,0,0,0) -- B:青

cv2.cvEllipse( img2, P1, S1, ell.angle, 0, 360, Sc1, 1, 8, 0 )
end

cv2.cvSaveImage( 'FitEllipse.tif', img2, 0 )
と云った感じ。

ここで、注意点

cvEllipseの第3引数、
即ち楕円のの指定は整数に成っている。
なので、四捨五入した方が宜しいようだ。


なお、
cvFitEllipse2の戻り構造体CvBox2Dの定義は、
<紙>流にしている。

要素の定義はフラットで、
{ x, y, xx, yy, angle }
最初の2つが中心、次の2つが径、最後が角度。


これで、やっと懸案事項が解決した。


本日はここまで。


Lua ( GSL Shell ) / OpenCV 学習は続く。


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒ blogram投票ボタン


170628
スポンサーサイト

OpenCV 2.3.1 でも変わらない?

2017-07-29 :  PCクリニック
前(2017-07-28)の記事:
LuaCV:OpenCV library wrapper for Lua language」では、

LuaCVを使うと、(基本)LuaからOpenCV 2.3.1を使える。
そして、FindContoursが正常に動作した。

なので、GSL Shellから使えるOpenCV 2.3.1を探してみた。
つまり、今使っているOpenCV 3.0.0の“DLL”じゃなくて、
古いバージョンの“DLL”



Index of /project/opencvlibrary」の中から、
opencv-win/ に行き、
2.3.1/ を選び、
OpenCV-2.3.1-win-superpack.exeをダウンロードした。
  2011-08-18 05:06 付 124MB

これ(~.exe)を“Explzh”で開き、
“build”フォルダの中の“x86”の中の“mingw”の中の“bin”に、
13個の“DLL”がある。
“opencv_”で始まる12個の“DLL”を頂いた。


それで、“cvcv.lua”で、ヘッダーファイルを作り、
ダメだった最初(2017-07-21)の記事「GSL Shell/OpenCV 学習:cvFitEllipse2
のコードを真似てコーディングしてみた。

途中、“DLL”が複数に分かれているので苦労したが、
以下で動いた:
----- FindContours_2.3.1.gsl -----
cvc = ffi.load( 'opencv_core231' )
cvi = ffi.load( 'opencv_imgproc231' )
cvh = ffi.load( 'opencv_highgui231' )

require'cvcv'

img = cvh.cvLoadImage( 'Threshold.tif', 0 )
xx, yy = img.width, img.height
sz = ffi.new( 'CvSize', xx, yy )

img2 = cvc.cvCreateImage( sz, 8, 3 )
cvi.cvCvtColor( img, img2, 8 )

storage = cvc.cvCreateMemStorage( 0 )

contours=ffi.new('CvSeq*[1]')
r = cvi.cvFindContours( img, storage, contours, 88, 1, 2 )
print( 'OK' , r ) ----- 確認用

it=ffi.new('CvTreeNodeIterator[1]')
cvc.cvInitTreeNodeIterator( it, contours[0], 3 )

i=0
while true do
contour = ffi.cast( 'CvSeq*', cvc.cvNextTreeNode( it ) )
if contour == nil then break end
print( contour.total, contour ) ----- 確認用

ell = cvi.cvFitEllipse2( contour )
print( ell.x, ell.y, ell.r1, ell.r2, ell.angle ) ----- 確認用

P1=ffi.new('CvPoint'); S1=ffi.new('CvSize')
P1.x, P1.y = ell.x, ell.y
S1.width, S1.height = ell.r1/2, ell.r2/2
Sc1=ffi.new('CvScalar'); Sc1.v1=255
cvc.cvEllipse( img2, P1, S1, ell.angle, 0, 360, Sc1, 1, 8, 0 )
end

cvh.cvSaveImage( 'Fit_By_CV231.tif', img2, 0 )
cvc.cvClearMemStorage(storage)
でしょうか?

やはり、“P1.x”“P1.y”つまり、近似楕円の中心点が不正?


結局、常用の“OpenCV 3.0.0”と変わらなかった。

再度出直しダ。


本日はここまで。


Lua ( GSL Shell ) / OpenCV 学習は続く。


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒ blogram投票ボタン


170624

LuaCV:OpenCV library wrapper for Lua language

2017-07-28 :  PCクリニック
以前(2017-07-21)の記事「GSL Shell/OpenCV 学習:cvFitEllipse2」以来、
“GSL Shell”でのOpenCVでは、
画像内のコンター(群)を求めるcvFindContoursの動作不正?の原因が分からない。


それで、「Lua OpenCV」で検索していたら、・・・・・
“GitHub”に、
marcoscoffier/lua---opencv: bindings to some parts of …

satoren/luaOpenCV: OpenCV wrapper for Lua
が見つかる。
しかし、これらはソースコードのみ。

更に探していたら、
“SourceForge.net”の「LuaCV download
が見つかった。

ここで、右にある大きい緑の「Download」ボタンではなくて、
その下にある、普通サイズ文字:
Browse All Files」からは、
Binariesが見つかった。

「LuaCV.exe」の他に、
「lua.zip」「luacv.zip」「opencv.zip」の3つの書庫がある。
それぞれの中身は、4ファイル、3ファイル、12ファイル。
これらを一箇所に展開した。
重複するので結果15ファイル。
OpenCVのバージョンは2.3.1で、
Luaは、5.2.0だった。

そこで、1本コーディングしてみた;
----- test_FindContors.lua -----
cv = require'luacv'

img2 = cv.LoadImage( 'Threshold.tif' ) -- これはカラーモードで読み込み
xx, yy = img2.width, img2.height
sz = cv.Size( xx, yy )

img1 = cv.CreateImage( sz, cv.IPL_DEPTH_8U, 1 ) -- GrayScale 用領域
cv.CvtColor( img2, img1, cv.CV_BGR2GRAY )

---------- 以下でテスト
storage = cv.CreateMemStorage()
a, contours = cv.FindContours( img1, storage, cv.CvContour["size"], cv.CV_RETR_LIST, cv.CV_CHAIN_APPROX_SIMPLE, cv.Point(0,0) )
print( contours ) -- 確認用
while contours do
print( contours.total ) -- 確認用
for i=1,5 do
w = cv.GetSeqElem( contours, i, cv.CvPoint["name"] )
io.write( w.x , ' ', w.y , ' ' ) -- 確認用
end print()
for i=k-4,k do
w = cv.GetSeqElem( contours, i, cv.CvPoint["name"] )
io.write( w.x , ' ', w.y , ' ' ) -- 確認用
end print()
contours=contours.h_next
end
でイイのかな?

そして、その場でDOSプロンプトで
Lua  test_FindContors.lua
としたら、
出来ているようダ。

続けて、楕円フィッティングをやってみた:
----- test_FindC_FitEs.lua -----
cv = require'luacv'

img2 = cv.LoadImage( 'Threshold.tif' ) -- これはカラーモードで読み込み
xx, yy = img2.width, img2.height
sz = cv.Size( xx, yy )

img1 = cv.CreateImage( sz, cv.IPL_DEPTH_8U, 1 ) -- GrayScale 用領域
cv.CvtColor( img2, img1, cv.CV_BGR2GRAY )

---------- 以下でテスト
storage = cv.CreateMemStorage()
a, contours = cv.FindContours( img1, storage, cv.CvContour["size"], cv.CV_RETR_LIST, cv.CV_CHAIN_APPROX_SIMPLE, cv.Point(0,0) )

while contours do
z = cv.FitEllipse2( contours )
print( z["center"].x, z["center"].y, z["size"].width, z["size"].height, z["angle"] ) -- 確認用
cv.Ellipse( img2, cv.Point(z["center"].x,z["center"].y), cv.Size(z["size"].width/2,z["size"].height/2), z["angle"], 0, 360, cv.Scalar(0,0,255), 1, 8,0 )
contours=contours.h_next
end
cv.SaveImage( 'LuaCV.png', img2 )
cv.ClearMemStorage( storage )
でしょうか?

キッチリ結果が出ていた。


これで行けると良いが、
これは、LuaJITに対応していない!

4月(2017-04-21)の記事:
call_Lua52 似非モジュール(基本Lua呼び出し)
で書いた方式でも一応出来たが???


どうしようかナ???


本日はここまで。


Lua ( GSL Shell ) / OpenCV 学習は続く。


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒ blogram投票ボタン


170623

OpenCV 学習:輪郭追跡処理

2017-07-26 :  PCクリニック
前(2017-07-24)の記事「GSL Shell/OpenCV 学習:輪郭(エッジ)検出」では、
  ・・・・・
  ・・・・・
  だが、これではcvFindContoursの代替にはならない。
  つまり、輪郭画素の位置データが得られない?
  ・・・・・
  ・・・・・
で終わっていた。


そこで、
輪郭座標取得処理に関して、Web検索した。

「画像処理ソリューション」サイトの“画像処理”に
輪郭追跡処理アルゴリズム」を見つけた。

  二値化された画像において、
  各連結部分の境界部分を求める事を輪郭追跡といいます。
  この輪郭追跡を行う事で周囲長や連結領域の幅や高さなどを
  求めることが出来ます。

  以下、この輪郭追跡の処理アルゴリズムを紹介します。
  ・・・・・
  ・・・・・

これを頂き、
Lua ( GSL Shell ) で、<紙>流コーディングを行った。

----- test_Search_Edge.gsl -----

-- BT : 二値化された画像(バイトデータ)

-- XT、YT : 輪郭点座標テーブル
XT, YT = matrix.new( 10000, 1 ), matrix.new( 10000, 1 )

function setP(x,y)
if x~=xs or y~=ys then
m=m+1; XT[m],YT[m]=x,y; xs,ys=x,y
end
end

-- 8方向座標差分 & 検出処理
VXY={ {-1,1}, {0,1}, {1,1}, {1,0}, {1,-1}, {0,-1}, {-1,-1}, {-1,0} }
function chkBT(V) v=V
while BT[(y+VXY[v+1][2])*xx+(x+VXY[v+1][1])]==0 do v=(v+1)%8 end
return v, x+VXY[v+1][1], y+VXY[v+1][2]
end

----- 取り敢えず1つの塊についての処理:
m = 0 -- 輪郭点の数

while true do
xs,ys=0,0 -- 1つ前の座標

----- 開始点(x0,y0)探索
y0=-1
for y=0,yy-1 do
for x=0,xx-1 do
if BT[y*xx+x]>0 then y0=y; x0=x; break end
end
if y0>-1 then break end
end
if y0<0 then break end -- {y0,x0}
print( x0, y0 ) -- 確認用
y,x=y0,x0; setP(x,y); Vold=-6; y1=y0
while true do
V,x,y = chkBT((Vold+6)%8)
if y>y1 then y1=y end
if x==x0 and y==y0 then break end
setP(x,y); Vold=V
end
end
------ これで、輪郭検出終了
print( m ) -- 確認用
--[[
  以降は、
  以前(2017-07-22)の記事「GSL Shell/OpenCV 学習:cvFitEllipse2 は正常
  のコードで、楕円フィッティング
]]
これでは?

輪郭点の数は、
“cvFindContours”で見つけるものより多い(?)が、
これで、代替は可能?


本日はここまで。


Lua ( GSL Shell ) / OpenCV 学習は続く。


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒ blogram投票ボタン


170622

GSL Shell/OpenCV 学習:輪郭(エッジ)検出

2017-07-24 :  PCクリニック
前(2017-07-22)の記事「GSL Shell/OpenCV 学習:cvFitEllipse2 は正常
では、“cvFitEllipse2”の正常動作を確認できた。

すると、
“cvFindContours”が問題と云うことだが、
どう足掻いても分からない。

そこで、代替手段が無いか探してみた。

エッジ検出(Sobel,Laplacian,Canny)」はどうか?

(1) 画像を準備して、
(2) Sobelオペレータを用いて,1次微分画像を求め、
(3) 画像のラプラシアン(2次微分)を求め、
(4) Cannyアルゴリズムを用いて,エッジを検出。

と云うこと。


このページにある、C言語コードを頂いた。


出来上がったコード:
---- GSL Shell コード
cv2 = require'cv2'
ffi.cdef[[
/****************************/
/* 不足分の関数宣言を記述 */
/****************************/
]]
-- (1) 二値化された画像入力 & 各種画像領域確保:
src_img = cv2.cvLoadImageM( 'sample.tif', 0 )
xx, yy = src_img.xx, src_img.yy
tmp_img = cv2.cvCreateMat( yy, xx, 5 ) ------ CV_32FC1
sobel_img = cv2.cvCreateMat( yy, xx, 0 ) ------ CV_8UC1
laplaian_img = cv2.cvCreateMat( yy, xx, 0 )
canny_img = cv2.cvCreateMat( yy, xx, 0 )

-- (2) Sobelオペレータを用いて,1次微分画像を求め、
cv2.cvSobel ( src_img, tmp_img, 1, 1, 3 )
cv2.cvConvertScaleAbs( tmp_img, sobel_img, 1, 0 )

-- (3) 画像のラプラシアン(2次微分)を求め、
cv2.cvLaplace( src_img, tmp_img, 3 )
cv2.cvConvertScaleAbs( tmp_img, laplaian_img, 1, 0 )

-- (4) Cannyアルゴリズムを用いて,エッジを検出。
cv2.cvCanny( src_img, canny_img, 50.0, 200.0, 3 );

----- 確認用に、画像出力:
cv2.cvSaveImage( 'Canny_img.tif', canny_img, 0 )
これで、
輪郭画像が得られた。


だが、これではcvFindContoursの代替にはならない。

つまり、輪郭画素の位置データが得られない?

もっと、学習が必要だ。


本日はここまで。


Lua ( GSL Shell ) / OpenCV 学習は続く。


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒ blogram投票ボタン


170618

GSL Shell/OpenCV 学習:cvFitEllipse2 は正常

2017-07-22 :  PCクリニック
前(2017-07-21)の記事「GSL Shell/OpenCV 学習:cvFitEllipse2」では、
“cvFindContours”と“cvFitEllipse2”の2段階の結果が変だったので、
どちらで異常となっているのか?
判別のために、“cvFitEllipse2”について確認してみた。


参考サイトとして、
ランダムな点列を包含する矩形 - OpenCV.jp」で、
“2次元座標列の生成”=cvSeqPushを学習した。


頑張って書いてみた:
---- GSL Shell コード
cv2 = require'cv2'
ffi.cdef[[
/****************************/
/* 不足分の関数宣言を記述 */
/****************************/
]]
storage = cv2.cvCreateMemStorage( 0 )

points = cv2.cvCreateSeq( 12, -- /* CV_32SC2 : CV_SEQ_ELTYPE_POINT */
56, -- /* sizeof(CvSeq) */
8, -- /* element size : int 2つ分 */
storage -- /* the container storage */
)
X=ffi.new('int32_t[8]', 35, 46, 48, 39, 26, 21, 26, 35 )
Y=ffi.new('int32_t[8]', 22, 26, 43, 51, 50, 40, 28, 23 )
P1=ffi.new('CvPoint')

for i=0,7 do
P1.x=X[i]; P1.y=Y[i]
_ = cv2.cvSeqPush( points, P1 )
end

ell = cv2.cvFitEllipse2( points )

これで得られた ellCvBox2D
で確認した“中心点”“2つの径”“角度”は正しそう。


とすると、cvFindContours処理が問題?


本日はここまで。


Lua ( GSL Shell ) / OpenCV 学習は続く。


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒ blogram投票ボタン


170616

GSL Shell/OpenCV 学習:cvFitEllipse2

2017-07-21 :  PCクリニック
このところ、Python プログラムを“GSL Shell”に移植している。

その中で“楕円フィッティング”の処理コードが出てきた。

当時の“Python”版については、
一昨年8月(2015-08-18)の記事:
Python/OpenCV 学習:cv2.fitEllipse」で書いた如く、・・・

(1)cv2.findContoursによって、画像内のコンター(群)を求める。

(2)各コンター cnt に対して、cv2.fitEllipseによって、
    ・中心座標
    ・2つの径
    ・角度(X軸開始、時計回り)
   を求める。

と云う手順で、実際のコード(例)は:
#### Python コード
#### ・・・・・
#### Bimg : 二値化済画像
_, contours, _ = cv2.findContours( Bimg, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE )

for m in range( len(contours) ):
cnt = contours[m]
ellipse = cv2.fitEllipse( cnt )
# これで、中心点、2つの径、角度(時計回り) を、実数値で得る

#### ・・・・・
の様。


これに対して“GSL Shell”では、
昨年3月(2016-03-26)の記事:
GSL Shell 学習:“cv2.lua”モジュール自作」で書いた如く、
“OpenCV”のdll利用、即ち C 言語版を使う。


それから、
参考サイトとして、
opencv.jp - OpenCV 計算幾何(Computational Geometory)サンプルコード
の2番目の、
  楕円のフィッティング cvFitEllipse2
  求めた輪郭に対して,楕円をフィッティングする
の、
  “サンプルコード”
も参考にし、

頑張って書いてみた:
---- GSL Shell コード
cv2 = require'cv2'
ffi.cdef[[
/****************************/
/* 不足分の関数宣言を記述 */
/****************************/
]]
---- ・・・・・
storage = cv2.cvCreateMemStorage( 0 )
contours=ffi.new( 'CvSeq*[1]' )
r = cv2.cvFindContours( Bimg, storage, contours, 88, 3, 2 )
it=ffi.new('CvTreeNodeIterator[1]')
cv2.cvInitTreeNodeIterator( it, contours[0], 3 )

while true do
cnt = ffi.cast( 'CvSeq*', cv2.cvNextTreeNode( it ) )
if cnt == nil then break end
ell = cv2.cvFitEllipse2( cnt )
-- この ell が CvBox 型データで、中心点等々を得られる。

---- ・・・・・
と云った感じ。



ところが、
何故か?2つの径、角度 は合っている?
しかし、中心点 がデタラメ???



頭を冷やして出直しダ。


本日はここまで。


Lua ( GSL Shell ) / OpenCV 学習は続く。


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒ blogram投票ボタン


170607-12

Lua ( GSL Shell ) 学習:DLL 呼び出し

2017-07-19 :  PCクリニック
このところ、Python プログラムを“GSL Shell”に移植している。

その中で“DLL 呼び出し”処理のコードが出てきた:

“MinGW”で自作した“Sub.dll”内の“Fun”関数を呼び出し実行するもの。
##### hogehoge.py ####
### inIMG 設定済み

import ctypes
import numpy as np
from PIL import Image

IN = Image.open( inIMG )
(xx, yy) = IN.size
INimg = np.array( IN.getdata(), np.uint8 ).reshape( ( yy, xx ) )

k_lib = ctypes.CDLL( 'Sub.dll' ) # dll 読み込み

iT = np.arange( 1, dtype=ctypes.c_ubyte ) # == 先ず属性を定義して、
iT = INimg # == 代入する。

################# dll 内の Fun 関数実行:
k_lib.Fun( xx, yy, iT.ctypes.data_as(ctypes.POINTER(ctypes.c_ubyte)) )
##### ・・・・・
の様なコード

これ(DLL呼び出し)に関しては、
昨年4月(2016-04-20)の記事「Lua - dll 連携:コールバック処理」が
まとめ的なもの。


なので、上記“Python”コードは、
以下の様な“GSL Shell”コードに変換できる:
----- hogehoge.gsl -----
ffi.cdef[[
typedef unsigned char Byte;
int Fun( int, int, Byte* );
]]
cv2 = require'cv2'
img = cv2.cvLoadImageM( charA(inIMG), 0 )
xx, yy = img.xx, img.yy

k_lib = ffi.load( 'Sub' ) -- dll 読み込み

----------------- dll 内の Fun 関数実行:
k_lib.Fun( xx, yy, img.Byte )
----- ・・・・・
OKダ。


本日はここまで。


Lua ( GSL Shell ) / FFI 学習は続く。


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒ blogram投票ボタン


170531

OpenCV 学習:画像サイズ変更

2017-07-17 :  PCクリニック
このところ、Python プログラムを“GSL Shell”に移植している。

その中で“画像の拡大(2次元補間)”処理のコードが出てきた。

これに関しては、
昨年6月(2016-06-04)の記事「GSL Shell:2次元補間(interp2d)」で、
  ・・・・・
  ・・・・・
  画像データに限定すると、“OpenCV”ではどうか?
  「cvResize」でしょうか?
  でも、いろいろ試してみたが結果がオカシイ???
  ・・・・・
  ・・・・・
と書いていた。


ここで、
改めて“OpenCV 2.4.13.2 documentation”を見てみた:
void cvResize( ・・・ )
void cvResize( const CvArr* src, CvArr* dst, int interpolation=~ )
  src - 入力Image
  dst - 出力Image
  interpolation -
    INTER_NEAREST - ・・・
    INTER_LINEAR - ・・・
    INTER_CUBIC - ・・・
    INTER_AREA - ・・・
    INTER_LANCZOS4 - ・・・
とある。


そこで、念のためテストしてみた:
----- test_Resize.gsl -----
local cv2 = require'cv2'
-- 自作 'cv2.lua' に不足している宣言を追加
ffi.cdef[[
void cvResize( const CvArr* src, CvArr* dst, int interpolation );
]]
------------------------------------------
---------- GrayScale画像
-- 元データ
img=cv2.cvLoadImageM( 'Gray.tif', 0 )
xx, yy = img.xx, img.yy

-- 拡大データ領域
m = cv2.cvCreateMat( 2*yy, 2*xx, 0 ) -- 0:CV_8UC1

cv2.cvResize( img, m, 1 ) -- 1:INTER_LINEAR
cv2.cvSaveImage( 'outGray.tif', m, 0 )

------------------------------------------
---------- カラー画像
-- 元データ
img=cv2.cvLoadImageM( 'Color.png', 1 )
xx, yy = img.xx, img.yy

-- 拡大データ領域
m = cv2.cvCreateMat( 2*yy, 2*xx, 16 ) -- 16:CV_8UC3

cv2.cvResize( img, m, 1 ) -- 1:INTER_LINEAR
cv2.cvSaveImage( 'outColor.png', m, 0 )
これで出来ました。


過去記事ではなぜ出来なかったのかナ???


本日はここまで。


Lua ( GSL Shell ) / OpenCV 学習は続く。


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒ blogram投票ボタン


170602

gnuplot 学習:極座標モード

2017-07-15 :  PCクリニック
このところ、Python プログラムを“GSL Shell”に移植している。

その中で“ローズダイアグラム”描画処理があった。

これは、
過去記事:「Python 学習:polar_bar_chart
そのもの?

過去記事:「ローズダイアグラム って何?」では、
  ・・・・・
  ・・・・・
  「Gnuplot」では?
  「レーダーチャート」のみ?
  ・・・・・
  ・・・・・
と書いていたが、・・・・・


改めて「gnuplot 極座標」で検索してみた

いろいろ見つかるが、・・・・・

ふと、
折線で、高さ?に相当する r をゼロにしたりして行たらどうなる?
そして、filledc パラメータを指定する。

これで出来るのではないか?

と云うことで、試してみた:
##### sample_polar.plt #####
$D << EOD
4.99 0
5 20 # 10-5+5
15 20
15.01 0
114.99 0
115 30 #120-5+5
125 30
125.01 0
244.99 0
245 30 #250-5+5
255 30
255.01 0
EOD
set terminal wxt size 400, 400
unset key
set polar
set angles degrees # 0度は右方向で、反時計回り
set grid polar
unset xtics
unset ytics

set xrange [-31.5:31.5]
set yrange [-31.5:31.5]
unset border
plot $D w filledc lc rgb "red"
これで、
3方向に伸びた“ローズダイアグラム”と云える?


これで、行こう。


本日はここまで。


Lua / gnuplot 学習は続く。


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒ blogram投票ボタン


170605

afxLua / winman 実用的な? 応用例

2017-07-14 :  PCクリニック
このところ、Python プログラムを“GSL Shell”に移植している。

その中で“WinPython 標準”の
win32apiwin32com を使った処理コードが出てきた:
##### hogehoge.py
import win32api
import win32com.client
import string
###### ・・・・・
ww = raw_input( '6 int. number(xx,yy,x0,y0,d,th2)+[Ret]:' )
w = ww.translate( string.maketrans( ',', ' ' ) )
v = w.split()
xx = int(v[0]); yy = int(v[1]); ###### ・・・・・

shell = win32com.client.Dispatch( 'WScript.Shell' )
shell.Run( 'notepad' )
win32api.Sleep(100)

###### ・・・・・
shell.SendKeys( '%d %d %d' % ( x, y, th2) )
shell.SendKeys( '{ENTER}' )
といった様なコード。

これなら、
過去記事:「afxLua / winman (続)
と大差ない?

変換作業を行ってみた:
----- use_afxLua_winman.gsl -----
require'pl'
require'winman'

io.write( '6 int. number(xx,yy,x0,y0,d,th2)+[Ret] : ' )
ww = io.read()
w = string.gsub( ww, ',', ' ' )
v = stringx.split(w)
xx = v[1]+0; yy = v[2]+0 ----- ・・・・・

os.execute( 'start notepad' )
note = winman.find{matchtitle=".+メモ帳$", wait=4000}
note:activate(); winman.sleep(50) -- int_msec

------ ・・・・・
winman.send( string.format('%d %d %d' , x, y, th2 ) )
winman.send( '{ENTER}' )
でどうかな?


良さそうダ。


本日はここまで。


GSL Shell / afxLua ライブラリの学習は続く。


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒ blogram投票ボタン


170601,05

OpenCV 学習:画像群から .avi ファイル作成

2017-07-12 :  PCクリニック
このところ、Python プログラムを“GSL Shell”に移植している。

その中で“画像群から .avi ファイル作成”処理コードが出てきた:
##### hogehoge.py
###### INdir, OTfile, fps は、設定済。

import cv2

os.chdir(INdir); flist=os.listdir('.');
img = cv2.imread( flist[0] ); os.chdir('..')
yy, xx, layers = img.shape

codec = 'CVID'
fourcc = cv2.VideoWriter_fourcc( *codec )
video = cv2.VideoWriter( OTfile, fourcc, fps, ( xx, yy ) )

os.chdir( INdir )
for IN in flist:
img = cv2.imread( IN )
video.write( img )
os.chdir( '..' )

video.release()
#####
の様なコード。つまり、
Python/OpenCV 学習:OpenCV 3.0 gold 導入”で書いた
“OpenCV”を使っている。

これなら、
“GSL Shell”に移植するのはほぼ“右から左”で出来る?

ここで、
気になるのは、
   codec  = 'CVID'
fourcc = cv2.VideoWriter_fourcc( *codec )
のところ。


Web検索で“参考サイト”を探してみた。

“OpenCV 3.0.0-dev documentation”の
Creating a video with OpenCV

“可変ブログ”の
OpenCVのVideoWriterを使って画像から動画を作る。

“tessy.org”の
ビデオの出力 - AkiWiki


これらを参考に、学習した。

以下のマクロが定義されている様ダ。
CV_FOURCC(c1,c2,c3,c4)   (((c1)&255) + (((c2)&255)<<8) + (((c3)&255)<<16) + (((c4)&255)<<24))
と云うことは、
codec  = 'CVID'
fourcc = ffi.cast( 'int32_t*', codec ) [0]
とすればイイ?


それで、頑張って移植してみた:
----- make_avi.gsl -----
------ INdir, OTfile, fps は、設定済。
--------------------------------------
cv2 = require'cv2'
ffi.cdef[[
typedef struct CvSize{ int xx; int yy; } CvSize;
void* cvCreateVideoWriter( const char* fname, int fourcc, double fps, CvSize frame_size, int is_color );
int cvWriteFrame( void* writer, const IplImage* image );
void cvReleaseVideoWriter( void** writer );
]] ----- 上記の 'void*' は、正しくは 'CvVideoWriter*'

codec = 'CVID'
fourcc = ffi.cast( 'int32_t*', codec ) [0]

require'pl'
flist=dir.getfiles( INDir )
img = cv2.cvLoadImageM( flist[1], 1 ) --- 'BGR' で読み込み
SZ=ffi.new( 'CvSize', img.xx, img.yy )

video = cv2.cvCreateVideoWriter( OTfile, fourcc, fps, SZ, 1 )

for z=1,#flist do
img = cv2.cvLoadImage( flist[z], 1 ) -- IplImage のみ可(CvMat 不可)?
cv2.cvWriteFrame( video, img )
end

cv2.cvReleaseVideoWriter( ffi.new( 'void*[1]', video ) )
で行けました。


本日はここまで。


Lua ( GSL Shell ) / OpenCV 学習は続く。


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒ blogram投票ボタン


170605

OpenCV 学習:画像・回転変換処理

2017-07-10 :  PCクリニック
このところ、Python プログラムを“GSL Shell”に移植している。

その中で、画像を回転する処理コードが出てきた:
##### hogehoge.py
r = 10 # 回転角度 ( 反時計回りの“度”。実数可 )
Cp='C:/_kami_/convert'; vpb='-virtual-pixel black'; rr=str(0-r)

inF=INdir+'/'+fnm; otF=OTdir+'/'+fnm
subprocess.call('%s %s -distort SRT %s %s %s' % (Cp, vpb, rr, inF, otF))
#####
つまり、
“Python”では“ImageMagick:画像形式変換ツール”の convert を使って、
convert -virtual-pixel black -distort SRT -10 <入力画像> <出力画像>
の様にして(例えば)10度回転変換を実行。
ここで、回転角度は(convertでは)時計回りなので、
反時計回りで実行したいので、負数にしている。

これをGSL Shellで行うには、
やはり「画像処理は、OpenCV で」でしょうか。


「OPenCV 画像 回転」で検索して、
OpenCVの画像処理
を見つけた。

このページの“4.画像回転”のコードを頂いた。


結果:
----- Rot.gsl -----
cv2 = require'cv2'
ffi.cdef[[
typedef struct CvPoint2D32f{ float x; float y; } CvPoint2D32f;
void cvResize( const CvArr* src, CvArr* dst, int interpolation );
CvMat* cv2DRotationMatrix( CvPoint2D32f center, double angle, double scale, CvMat* map_matrix );
void cvWarpAffine( const CvArr* src, CvArr* dst, const CvMat* map_matrix );
void cvGetQuadrangleSubPix( const CvArr* src, CvArr* dst, const CvMat* map_matrix );
]]----- 自作 'cv2.lua' に不足している宣言を追加

Pxy32F=ffi.new('CvPoint2D32f')
function setPxy32F(x,y) Pxy32F.x=x Pxy32F.y=y end

-- // 入力画像読み込み
img = cv2.cvLoadImageM( 'sample.png', 1 )
xx, yy = img.xx, img.yy

-- // 出力用領域
img2 = cv2.cvCreateMat( yy, xx, 16 ) -- CV_8UC3

-- // 回転中心
setPxy32F( xx/2, yy/2 )

-- // 回転角度(degree) ( 正:右回転 / 負:左回転 )
angle_deg = -30.0

-- // スケーリング係数
scale = 1

-- // 回転行列領域確保
rotationMat = cv2.cvCreateMat( 2, 3, 5 ) -- CV_32FC1

-- // 回転行列設定
cv2.cv2DRotationMatrix( Pxy32F, angle_deg, scale, rotationMat )

-- // 回転実行
cv2.cvWarpAffine( img, img2, rotationMat )

-- // 画像出力
cv2.cvSaveImage( 'Rot_img.png', img2, 0 )
で行けました。


本日はここまで。


Lua ( GSL Shell ) / OpenCV 学習は続く。


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒ blogram投票ボタン


170603

OpenCV 学習:GrayScale/'RGB' 変換

2017-07-08 :  PCクリニック
このところ、Python プログラムを“GSL Shell”に移植している。

その中で、こんなコードが出てきた:
from  PIL import Image
img = Image.open( inp_tif )
img = img.convert( 'RGB' )
IMG = img.load()
##### IMG 加工
img.save( out_png )
これを作った頃は、“Pillow”だった?

それで、
この処理を“GSL Shell”で書くなら、やはり“OpenCV”ですネ:
cv2 = require'cv2'
img = cv2.cvLoadImageM( inp_tif, 1 ) -- 'BGR' で読み込む
----- img 加工
cv2.cvSaveImage( out_png, img, 0 )
の様に、読み込み時に変換する?

cvLoadImageM関数の第2引数:
 -1 ・・・ ありのままに読み込む
 0 ・・・ GrayScale で読み込む
 1 ・・・ 'BRG'カラーで読み込む


ところが今回、今更ながら“OpenCV”では、
読み込み済み画像の色数変換が出来ることを知った。
void cvCvtColor( const CvArr* src, CvArr* dst, int code );
なる関数が使えた。

それで、第3引数の“code”値については、
CV_BGR2BGRA =0
CV_RGB2RGBA = CV_BGR2BGRA
CV_BGRA2BGR = 1
CV_RGBA2RGB = CV_BGRA2BGR
CV_BGR2RGBA = 2
CV_RGB2BGRA = CV_BGR2RGBA
CV_RGBA2BGR = 3
CV_BGRA2RGB = CV_RGBA2BGR
CV_BGR2RGB = 4
CV_RGB2BGR = CV_BGR2RGB
CV_BGRA2RGBA = 5
CV_RGBA2BGRA = CV_BGRA2RGBA
CV_BGR2GRAY = 6 // カラーから白黒
CV_RGB2GRAY = 7
CV_GRAY2BGR = 8 // 白黒からカラー
CV_GRAY2RGB = CV_GRAY2BGR,
CV_GRAY2BGRA = 9
CV_GRAY2RGBA = CV_GRAY2BGRA
CV_BGRA2GRAY = 10
CV_RGBA2GRAY = 11
・・・・・
ですね。


そうすると、・・・・・
cv2 = require'cv2'
ffi.cdef[[
void cvCvtColor( const CvArr* src, CvArr* dst, int code );
]]
img = cv2.cvLoadImageM( inp_tif, 0 ) -- 白黒 で読み込む
-----
-----
img2 = cv2.cvCreateMat( img.yy, img.xx, 16 ) -- カラー画像領域確保 ( CV_8UC3 )
cv2.cvCvtColor( img, img2, 8 ) -- 色数変換
----- img2 加工
cv2.cvSaveImage( out_png, img2, 0 )
の様になる。


本日はここまで。


Lua ( GSL Shell ) / OpenCV 学習は続く。


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒ blogram投票ボタン


170530,0603

Lua ( GSL Shell ) / Penlight 学習:range 関数

2017-07-07 :  PCクリニック
Python プログラムの“GSL Shell”への移植を行っている。
その作業で、“range 関数”が出てきた。

“Python”で云うところの“range”関数に関しては、
昨年2月(2016-02-09)の記事「GSL Shell 学習:fun 関数」で書いている。
  ・・・・・
  ・・・・・
local fun = require'fun'
for _, a in fun.range(3) do print(a) end
  ・・・・・
  ・・・・・

だら、このところPenlightが気に入っていて、
調べてみたら、
案の定あった。

Pythonで、
for k in range( n ) :   # ~ #
### とか、
for k in range( i, j ) : # ~ #
と記述する処は、

Lua ( GSL Shell )では、
require'pl'   ----- これ前提で、
for k in seq.range( 0, n-1 ) do -- ~ -- end
--- とか、
for k in seq.range( i, j-1 ) do -- ~ -- end
となる。


更なるPenlight学習で、・・・
plc = require'pl.comprehension'.new()
T = plc('x for x=1,10')()
とすることで、
配列 T は、 { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }
となる。
なお、
plc = require'pl.comprehension'.new()
T = plc'x for x=1,10'()
と括弧は省略出来る。

更に更に、GSL Shellの“matrix”ベクトルも作れる:
plc = require'pl.comprehension'.new()
T = matrix.vec( plc'x for x=1,10'() )
と云った具合。


本日はここまで。


Lua ( GSL Shell ) 学習は続く。


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒ blogram投票ボタン


170528,0605

Lua 学習:Rosetta Code サイト

2017-07-05 :  PCクリニック
Python プログラムの“GSL Shell”への移植を行っている。
その作業で、“文字列が数値を表すか?の判定”処理をどうするか悩んだ。


Python については、
“主にプログラムを勉強するブログ”」の「isdigit()について」がある。

Lua については、
最近填っている「Penlight」にも“isdigit”があった。

そこで、上記ブログのコードを流用して、Lua ( GSL Shell )で書いてみた:
----- test_use_penlight.gsl -----
require'pl'
SS = string.gsub( STR, '%.', '' )
if stringx.isdigit( SS ) then
-----
end
の様な感じ?

でも、些かスマートじゃない。


そんな時、
Determine if a string is numeric」なるページを見つけた。
=== (Google翻訳)
文字列が数値かどうかを判断する

このページには、
120の言語に対して、同じ機能を実現するコードが載っている。

で、60番目の Lua では、
if tonumber(a) ~= nil then
-- it's a number
end
  This will also accept strings like "0xFF" or "314.16e-2" as numbers.

と、ある。

tonumberだと、こんなにスマート。
しかも判定機能が豊富。

今更ながら、tonumber 関数を知った。
 目から鱗 が落ちた???



ところで、このページは何???

Rosetta Code」なるサイトの中の一ページ。

で、Rosetta Code サイトとは:

   Rosetta Code is a programming chrestomathy site.
   The idea is to present solutions to the same task in as
  many different languages as possible,
  to demonstrate how languages are similar and different,
  and to aid a person with a grounding in one approach to
  a problem in learning another.
   Rosetta Code currently has 851 tasks, 202 draft tasks,
  and is aware of 658 languages,
  though we do not (and cannot) have solutions to every task
  in every language.
=== ( Google 翻訳 )
   Rosetta Codeはプログラミングのchrestomathyサイトです。
   できるだけ多くの異なる言語で同じタスクにソリューションを提示し、
  言語がどのように似ていて異なっているかを実証し、
  ある人が別の方法を学習する際の問題へのアプローチを支援することです。
   Rosetta Codeは現在、851のタスクと202のドラフトタスクを持ち、
  658の言語を認識していますが、
  各言語のあらゆるタスクに対する解決策はありません。


これは、一読の価値がある有用なサイトですね。


本日はここまで。


Lua ( GSL Shell ) 学習は続く。


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒ blogram投票ボタン


170530

GSL Shell 学習:ヒストグラム(改)

2017-07-03 :  PCクリニック
Python プログラムの“GSL Shell”への移植を行っている。
その作業中に、昨年7月(2016-07-02)の記事「GSL Shell 学習:ヒストグラム
で書いたコードのミス(誤解)を見つけた。

つまり、
レンジ”の定義が2種類混在していた。


そこで、正しいものに書き換えた。

(1)3区間で、等間隔 { 4, 6.7, 9.3, 12 } とする場合:
----- test_Histo.gsl 改-1 -----
gsl = require'gsl'
v = ffi.new( 'double[10]',
{ 4, 5, 6, 7, 8, 9, 10, 11, 12, 4.5 } ) -- 元の値(テスト用)

h = gsl.gsl_histogram_alloc( 3 ) -- 区間数
gsl.gsl_histogram_set_ranges_uniform( h, 4, 12 ) -- 3区間で、等間隔 { 4, 6.7, 9.3, 12 }

for i=0,9 do
gsl.gsl_histogram_increment( h, v[i] ) -- 振り分け
end
for j=0,2 do print( h.bin[j] ) end -- 結果: 4, 3, 2  合計 9件でOK

gsl.gsl_histogram_free( h ) -- 後始末

(2)3区間で、指定間隔 { 4, 5, 8, 12 } とする場合:
----- test_Histo.gsl 改-2 -----
gsl = require'gsl'
v = ffi.new( 'double[10]',
{ 4, 5, 6, 7, 8, 9, 10, 11, 12, 4.5 } ) -- 元の値(テスト用)

h = gsl.gsl_histogram_alloc( 3 ) -- 区間数
bT = ffi.new('double[4]', 4, 5, 8, 12 ) -- 区間テーブル 各々 [ ~ )
gsl.gsl_histogram_set_ranges( h, bT, 4 ) -- 設定

for i=0,9 do
gsl.gsl_histogram_increment( h, v[i] ) -- 振り分け
end
for j=0,2 do print( h.bin[j] ) end -- 結果: 2, 3, 4  合計 9件でOK

gsl.gsl_histogram_free( h ) -- 後始末


要は、振り分けのための“ビン”の設定方法の違い。


本日はここまで。


Lua ( GSL Shell ) 学習は続く。


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒ blogram投票ボタン


170530

Lua ( GSL Shell ) / Penlight 学習:ディレクトリ一覧

2017-07-01 :  PCクリニック
とある Python プログラムを、“GSL Shell”に移植しようとした。

このプログラムの中に、ディレクトリ一覧取得処理が出てくる。

ファイル一覧に関しては、
何件か記事にしている が、
ディレクトリ一覧に関しては無かった。


ここはひとつ“Penlight”でしょうか?

ありました。
dirモジュールのgetdirectories関数(?)

Pythonコードで:
import os
f_list = os.listdir( Dir )
とすると、
f_list は、パス(Dir)内の全ファイルとディレクトリのリストとなる。

これに対して、GSL Shellでは:
require'pl'
d_list = dir.getdirectories( Dir )
for i, fn in ipairs( d_list ) do
d_list[i]=string.gsub( fn, Dir..'%\\', '' )
end
で、
s_list は、パス(Dir)内の全ディレクトリのリストとなる。


つまり、
Penlightでは、
-- ファイル一覧
f_list = dir.getfiles( Dir )

-- ディレクトリ一覧
d_list = dir.getdirectories( Dir )
の様に、個別に取得出来る。

但し、純粋なファイル名/ディレクトリ名だけでなく、
(相対)パス名となっている。


これに対しては、
pl.path.splitpathが用意されている。
p, ff = path.splitpath( f_list[i] )
p, dd = path.splitpath( d_list[i] )
とすると、
ffddが、
純粋なファイル名、ディレクトリ名だけになる。
( p は、空(empty) の場合も有り得る。)


本日はここまで。


Lua ( GSL Shell ) / Penlight 学習は続く。


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒ blogram投票ボタン


170530
おきてがみ/blogram
blogram投票ボタン



おきてがみ

最新記事
カレンダー
06 | 2017/07 | 08
- - - - - - 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 - - - - -
月別アーカイブ
カテゴリ
最新コメント
検索フォーム
リンク
プロフィール

<紙>

Author:<紙>
ようこそ。
「パソコンヲタクの雑記帳」
もろもろなことを綴っています。
パソコン ヲタクってねくら?
画像は kami でなく kani です。

カウンター(fc2、i2i) /Google Analytics


i2i(from 2010-08-24)
Total =
Today  =  
Yesterday=
アンチエイジング

Google Analytics
ブックマーク