以前紹介した MonoDouble ですが、その後も必要に応じて拡張しています。少しだけ紹介します。
- プロパティが増えました。前回はブロックはブロックサイズでしか移動しませんでしたが、個別に移動量(shiftWidht, shiftHeight)の設定も行えるようにしています。また、端への移動時に指定したブロックサイズよりも小さいブロックを許可するかどうかのフラグ(smallBlockOk)も追加しました。
classdef MonoDouble < handle properties buffer % array buffer bits % the number of bits blockWidth % width of block blockHeight % height of block shiftWidth % shift width of block shiftHeight % shift height of block nowx % x of now position (from 0 to width-1) nowy % y of now position (from 0 to height-1) block % reference for sub MonoDouble smallBlockOk % 0 ... smallBlockNo, 1 ... smallBlockOk end
- 周期拡張、対称拡張を追加しました。超富豪的プログラミングです。今やっている処理では最初に一回しか呼ばないので、効率よりもわかりやすさ優先で書いてます。
function self = extRing_(self, top, left, bottom, right) if nargin == 4 right= left; elseif nargin == 3 bottom = top; right = left; elseif nargin == 2 left = top; bottom = top; right = top; end b = self.buffer; mid = [b b b; b b b; b b b]; sy = self.height; sx = self.width; self.buffer = mid(sy-top+1:sy*2+bottom, sx-left+1:sx*2+right); end function self = extWS_(self, top, left, bottom, right) if nargin == 4 right= left; elseif nargin == 3 bottom = top; right = left; elseif nargin == 2 left = top; bottom = top; right = top; end b = self.buffer; ud = flipud(b); lr = fliplr(b); rt = fliplr(ud); mid = [rt ud rt; lr b lr; rt ud rt]; sy = self.height; sx = self.width; mid([sy, sy*2], :) = []; mid(:, [sx, sx*2]) = []; self.buffer = mid(sy-top:sy*2+bottom-1, sx-left:sx*2+right-1); end function out = extRing(self, top, left, bottom, right) if nargin == 2 out = self.copy.extRing_(top, top, top, top); elseif nargin == 3 out = self.copy.extRing_(top, left, top, left); elseif nargin == 4 out = self.copy.extRing_(top, left, bottom, left); else out = self.copy.extRing_(top, left, bottom, right); end end function out = extWS(self, top, left, bottom, right) if nargin == 2 out = self.copy.extWS_(top, top, top, top); elseif nargin == 3 out = self.copy.extWS_(top, left, top, left); elseif nargin == 4 out = self.copy.extWS_(top, left, bottom, left); else out = self.copy.extWS_(top, left, bottom, right); end end
- ブロック周りの初期設定処理を変更しました。引数が少ない場合は、前回と同じブロックサイズと同じ移動設定になります。ここを変えても、setBlock_ や getBlock_メソッドは変更ありません。
function self = setBlockSize_(self, by, bx, sbok, sy, sx) if by > self.height by = self.height; end if bx > self.width bx = self.width; end if nargin == 4 sy = by; sx = bx; elseif nargin == 3 self.smallBlockOk = 1; sy = by; sx = bx; else self.smallBlockOk = sbok; end self.blockWidth = bx; self.blockHeight = by; self.shiftWidth = sx; self.shiftHeight = sy; self.nowx = 0; self.nowy = 0; self.block = MonoDouble(zeros(self.blockHeight, self.blockWidth)); end
- next は大きく変わりました。smallBlock が許可される場合とされない場合では大きく違うので、別処理になっています。
function out = next_(self) if self.nowx == -1 out = 0; else out = 1; if self.smallBlockOk == 1 self.nowx = self.nowx + self.shiftWidth; if self.nowx >= self.width self.nowx = 0; self.nowy = self.nowy + self.shiftHeight; if self.nowy >= self.height self.nowx = -1; self.nowy = -1; out = 0; end end else self.nowx = self.nowx + self.shiftWidth; if self.nowx + self.blockWidth > self.width self.nowx = 0; self.nowy = self.nowy + self.shiftHeight; if self.nowy + self.blockHeight > self.height self.nowx = -1; self.nowy = -1; out = 0; end end end end end
- ブロック内の値の総和を得るメソッドを追加しました。
function out = sum(self) out = sum(sum(self.buffer)); end
- 以上の拡張によってブロックマッチングが、簡単に書けるようになったので、メソッド化しました。
function [out, vy, vx, min] = blockMatching(self, other) vy = 0; vx = 0; min = 1e300; oy = other.height; ox = other.width; self.setBlockSize_(oy, ox, 0, 1, 1); cond = true; while (cond) bk = self.getBlock_; se = bk.sub_(other).square_.sum; if se < min min = se; vy = self.nowy; vx = self.nowx; end cond = self.next_; end self.setBlockSize_(oy, ox); self.setNowPos(vy, vx); out = self.getBlock_; end
このメソッドを使った例は明日.