• 締切済み

MATLABのrbboxについての質問です。

MATLABのrbboxについての質問です。 MATLABである画像の領域内の情報を取得できるようにしたいのですが、調べてみると、rbboxという関数を使って出来るらしいです。実際にMATLABのHPにあったソースコードを動かしてみると、画像にマウスでドラッグした領域の枠が描かれるのですが、その画像の領域をどうやって処理を行えるように出来るのかがわかりません。出来れば教えてほしいです。rbboxのソースコードを下に示します。宜しくお願いします。 figure; pcolor(peaks); k = waitforbuttonpress; point1 = get(gca,'CurrentPoint'); % ボタンダウンの検出 finalRect = rbbox; % figure単位の出力 point2 = get(gca,'CurrentPoint'); % ボタンアップの検出 point1 = point1(1,1:2); % x と y の抽出 point2 = point2(1,1:2); p1 = min(point1,point2); % 位置と大きさの計算 offset = abs(point1-point2); % x = [p1(1) p1(1)+offset(1) p1(1)+offset(1) p1(1) p1(1)]; y = [p1(2) p1(2) p1(2)+offset(2) p1(2)+offset(2) p1(2)]; hold on axis manual plot(x,y,'r','linewidth',5) % ボックスの回りに選択した領域の描画

みんなの回答

  • Kules
  • ベストアンサー率47% (292/619)
回答No.2

ANo.1のKulesです。 ん~まあ先に切り出す先の行列を用意しといて 2重のforループで1個ずつ取り出してもいいんですが、 そんなことしなくても行列を行列として扱えて 表現がすっきり☆するのがMatlabのいいトコロ(?)なので それを利用しましょう。 答えを書いちゃうと1行で終了なんですが(笑)、 それだと何をしているのかさっぱりだと思うんで 簡単な解説を付けておきます。 ・[]内の行列表現において、,(カンマ)は横連結、;(セミコロン)は縦連結を表す 例えばA=[1,2,3]と書けばAは横ベクトル、A=[1;2;3]と書けばAは縦ベクトルになります。 ,はスペースで代用できますが、迂闊にスペースを使うと混乱するので私は,を使うようにしています。 ;も改行で代用できますが、これもやっぱり混乱を招くので;を使った方がいいでしょう。 ,と;を使えば行列は作れますが、各列での要素数、各行の要素数が一致していないと (要はちゃんとした長方形の行列になってないと)当然エラーになります。 ・:(コロン)は大きく2つの使い方がある。(1)単調数列を作る(2)ワイルドカードとして使う (1)(初項):(増分):(末項)で単調数列が作れます。ただし、初項と増分の値によっては末項にならないことがあるので、 その場合末項を超えない最大の値が末項になります。(1:2:10とした場合、末項は9) 増分は負の値も取れます。また、1の場合は省略することもできます(その場合:は1つでよい) これを使ったベクトルは、基本的に横ベクトルです。 (2)基本的に「全部」を表します。説明はもう少し後に書きます。 ・'(シングルコーテーション)は転置を表す まあ行列から値取り出したりするだけなら使わないと思いますが。 ・ベクトルから要素を取り出すには()を使う。()内では行列も使える。 A=1:10;とした時、例えば3つ目の要素を取り出すにはA(3)とします。 3つ目と5つ目の要素を取り出したければA([3,5])とします。 この時、A([3;5])としても結果は同じです。縦ベクトルか横ベクトルかは Aがどちらであるかに依存します。 A([1,3,5])とする時と、A(1:2:5)とする時は同じ結果が出ます。 最後の要素(今回は10)を指定する代わりに、endを使うこともできます。 さらに、A([3,5;4,6])とした場合、()の中が行列の形になってるので、出てくる結果も行列になります。 この時の行列のサイズは、()内に書いた行列のサイズに一致します。 ・行列から要素を取り出すには、(行,列)の順に指定。それぞれに行列を使用できる。 A=magic(10)とすることで10×10の行列ができますが、この中の上から3行目、左から2行目を取り出すには A(3,2)とします。上から3行目、左から2列目と4列目を取り出すには A(3,[2,4])とします。上から3行目と5行目、左から2列目と4列目を取り出すには A([3,5],[2,4])とします。(合計4つの値が取り出され、2×2の行列になります) 上から3行目を全部取りだしたい時は、A(3,:)とします。ここの:が上に書いた「ワイルドカード」の意味です。 行、列にそれぞれ行列を指定することはできますが、取り出され方が複雑になるのであまりオススメしません。 (どうなるかは自分で確かめてみると面白いかも知れません) と、ここまでの話を理解いただけると、 >RectLeft列からRectRight列までで、RectTop行からRectBottom行までのデータをどうすれば切り出すことができるのか というのが、イメージデータをCdataとした時、 Cdata(RectTop:RectBottom,RectLeft:RectRight)となることはわかると思います。 (これでもまだいくらかの話はすっ飛ばしてますが) 長文失礼しました。参考になれば幸いです。

  • Kules
  • ベストアンサー率47% (292/619)
回答No.1

先の質問で知らぬ間に昔私の回答したFigureTrimのプログラムを引用されてたKulesです。 あの関数あまりエラーに強くないんですよね…あの段階では。 あの後さらに個人的に作りなおしたやつはいい感じなんですが。 さて、このプログラム上においてのポイントは、 finalRectにはfigure内での[左端 下端 幅 高さ]の値がピクセル値で出ており、 point1,point2にはaxes内での座標が出ているということです。 で、欲しいのは画像内のデータということなので、 「point1,point2が画像データ(xdata、ydata、zdata、Cdata)においてどの範囲なのか」 を考えればよいことになります。 まあ普通にpcolorとかで絵を描けばxdata、ydataは整数値の座標で、Cdataもそれに対応した 各ピクセルの色を出しているかと思います。ですので、 point1、point2の座標をroundか何かで整数値に直してやり、Cdataを切り取るインデックスを 作ればいいのではないかと思います。 具体的には、 RectTop=min([point1(2),point2(2)]);←ボタンを押したところと離したところのうち、y座標が大きい方 RectBottom=max([point1(2),point2(2)]); RectLeft=min([point1(1),point2(1)]); RectRight=max([point1(1),point2(1)]); としてやれば、RectLeft列からRectRight列までで、RectTop行からRectBottom行までの データを切り出せばよい、ということになります。 まあこの辺りは先の質問で引用されていたFigureTrimの中で、Cutという関数の中を見てもらえれば よいかと思われます。 コメントをほとんど書いていないため、何をしているかわからないところに関しては補足していただければと思います。 結論からすると今回の用途においてrbboxは要らないですね(笑)使って書けなくもないと思いますが。 以上、参考になれば幸いです。

yuuwashock
質問者

補足

ご丁寧に回答ありがとうございます。 しかしながら、RectLeft列からRectRight列までで、RectTop行からRectBottom行までのデータをどうすれば切り出すことができるのかがわかりませんでした。出来れば教えていただけませんか。

関連するQ&A

  • MATLABのプログラミングについてご質問です(2)

    MATLAB初心者です。 現在、以下の環境を使っています。 ------------------------------- OS:Windows XP MATLABのバージョン:R2007a ------------------------------- 以下の内容をプログラムでどう組み込めばよいのか分らないため、質問させて頂きました。 詳しい方、ご教授のほどお願いします。 (1)例えば「512x512」サイズの画像を figure に表示させ、その画像の中点を表示させる方法  (画像の中点に「×」マークをつけるイメージです) (2)上記の画像からマウスを使って、座標の始点と終点をクリックしたら"□"(選択範囲)の枠が表示される方法  (マウスを使って画像サイズを小さくしたいのが目的です) (3)上記の画像からマウスを使って、クリックした場所の座標(x軸、y軸)を figure に表示させる方法   (4)uigetdir からディレクトリ選択画面を表示して、指定したディレクトリの絶対パスを取得する方法 (5)画像データを imwrite する時、指定したパス(ディレクトリ)に出力する方法 全てでなくても、判る範囲までのご回答でもかまいません。 よろしくお願いします。

  • MATLABの質問です。

    MATLABについての質問です。 大学の研究していてMATLABでわからないところがあるのでぜひ教えて頂けたらと思っています。 よろしくお願い致します。 現在任意の多角形障害物を設置し,それらを回避する折れ線経路を全部求めるところまでできています。その後、全経路からダイクストラの方法で最短折れ線経路を求めたいのですがどのようにプログラムを持っていけばいいか分からず手詰まりしました。 ぜひご指導いただけますでしょうか。 よろしくお願いいたします。 プログラムは動きます。 close all; clc; init=1; final=1000; %図形座標取得 figure(1) for loop=init:final [x,y] = ginput A=[x,y] if 0<=x(:,:)&x(:,:)<=1&0<=y(:,:)&y(:,:)<=1 B{loop} =A else break end end % size(B{i},1) figure(2) for C=init:loop-1 B{C} fill(B{C}(:,1),B{C}(:,2),'g');hold on axis([0,1,0,1]); end [x,y] = ginput pb=[x,y] figure(3) for C=init:loop-1 fill(B{C}(:,1),B{C}(:,2),'g');hold on axis([0,1,0,1]); plot(pb(:,1),pb(:,2),'o');hold on axis([0,1,0,1]); end %図形の辺 k=0; for i=1:loop-1 for p=1:size(B{i},1) for q=p+1:size(B{i},1) k=k+1; obst(k,:) = [B{i}(p,:),B{i}(q,:)]; end end end Pall = pb(1, :); Pall = [Pall; cat(1, B{:})]; Pall = [Pall; pb(2, :)]; %全経路 k=0 for i=1:size(Pall,1) for j=i+1:size(Pall,1) k=k+1; path(k,:) = [Pall(i,:),Pall(j,:)]; point{k}=[i,j]; end end % 交差判定 H=0 for j=1:size(path,1) cflas=1 for i=1:size(obst,1) y1=((obst(i,1)-obst(i,3))*(path(j,2)-obst(i,2))+(obst(i,2)-obst(i,4))*(obst(i,1)-path(j,1))) y2=((obst(i,1)-obst(i,3))*(path(j,4)-obst(i,2))+(obst(i,2)-obst(i,4))*(obst(i,1)-path(j,3))) y3=((path(j,1)-path(j,3))*(obst(i,2)-path(j,2))+(path(j,2)-path(j,4))*(path(j,1)-obst(i,1))) y4=((path(j,1)-path(j,3))*(obst(i,4)-path(j,2))+(path(j,2)-path(j,4))*(path(j,1)-obst(i,3))) Y1=y1*y2 Y2=y3*y4 if Y1<0&&Y2<0 H=H+1 cflas=0 S{j}=[0,0,0,0] S1{j}=[0,0,0,0] end end if cflas==1 X=[path(j,1),path(j,3)]; Y=[path(j,2),path(j,4)]; Xa=[path(j,1),path(j,2)]; Yb=[path(j,3),path(j,4)]; S{j}=[X,Y] S1{j}=[Xa,Yb] plot(X,Y,'-');hold on end end barricade = length(B{1,1}); M=zeros %コストを計算 for k = 1:size(path,1) X1=S{k}(1,1); X2=S{k}(1,3); Y1=S{k}(1,2); Y2=S{k}(1,4); cost{k}=sqrt((X2-X1)^2+(Y2-Y1)^2) M(point{k}(1), point{k}(2) )=cost{k} % if cost{i}==0 % cost{i}=10 % end end M' g=cost{1} for j=1:size(obst,1)+1 if(cost{j}>cost{j+1}) g= cost{j+1} end end

  • Matlabのオブジェクト

    例えば x=[1,1e8]; y=[1,1e4]; plot(x,y); とするとx軸の範囲は1~100万(厳密に指定しなければ0~100万になるはず)になります。 その時x軸のラベルは何も指定しなければグリッドに対応させて{'0','1','2',…'10'}となり、右下に'×10^7'の表記が出るかと思います。 この'×10^7'とは、何によって制御されているんでしょうか? 色々調べてみると、 get(gca,'Xtick');よりXtickの値は真値(0,10万,20万,…,100万)が入っている get(gca,'Xticklabel');を調べると[' 0';' 1';' 2';' 3';…;'10'];しか入っておらず、'×10^7'の情報は入っていない。 set(0,'ShowHiddenHandle','on');で不可視のオブジェクトも全て見えるようにして、h=findall(gcf);でfigureに含まれるオブジェクトのハンドルを全部とりだしたが、その中に'×10^7'の情報が含まれたオブジェクトは見つけられず。 といった感じです。 何がしたいかと言えば、'×10^7'の位置を自由に調整したいです。(これがtextオブジェクトならpositionプロパティがあるはずなので位置を動かせるハズ) 今はXdataを10万で割ることで'10^7'をデータからなくしてから、textを使って'×10^7'を任意の位置に貼り付けていますが、これだとデータを加工していることになりその後の処理をする上であまり嬉しくありません(他のデータも合わせてプロットする時、そのたびにxdataを調整するのがめんどくさい) Xdataを加工することなく、'×10^7'の位置だけを動かせるのがベストなんですが… この'×10^7'を制御しているオブジェクトはどこにあるんでしょうか?あるいは、どこで制御しているんでしょうか? よろしくお願い致します。

  • MATLABについての質問です。

    大学の研究していてMATLABでわからないところがあるのでぜひ教えて頂けたらと思っています。 よろしくお願い致します。 現在任意の多角形障害物を設置し,それらを回避する折れ線経路を全部求めるプログラムを作っているのですがどのように作ればいいかわかりません。 今は始点と終点を決めてクリックした所をつないでいくプログラムができたのですが問題文に沿ってできていません。 このプログラム後はダイクストラの方法で最短折れ線経路を求めるので それを含めてよろしくお願い致します。 clear all; close all; clc; init=1; final=1000; figure(1) for loop=init:final [x,y] = ginput A=[x,y] if 0<=x(:,:)&x(:,:)<=1&0<=y(:,:)&y(:,:)<=1 B{loop} =A else break end end figure(2) for C=init:loop-1 B{C} fill(B{C}(:,1),B{C}(:,2),'g');hold on axis([0,1,0,1]); end [x,y] = ginput pb=[x,y] figure(3) for C=init:loop-1 fill(B{C}(:,1),B{C}(:,2),'g');hold on axis([0,1,0,1]); plot(pb(:,1),pb(:,2),'o');hold on end for D=init:final [x,y] = ginput if 0<=x(:,:)&x(:,:)<=1&0<=y(:,:)&y(:,:)<=1 plot([pb(1,1),x',pb(2,1)],[pb(1,2),y',pb(2,2)],'-*');hold on node{D}=[[pb(1,1),x',pb(2,1)],[pb(1,2),y',pb(2,2)]] B{D} = sum(node{D}) else break end end for E=init:D-1 B{E} end

  • MATLAB初心者です。教えてください

    MATLABにて画像のようなグラフを作りたいのですが、plotyyなどを使って作ろうとしてどうしてもできずに困っています。 左の画像から右の画像に変形させたいのです。 -10x<-5,5<x<10のyが二次関数のような曲線でそれ以外は水平です。 なにかいい方法が無いでしょうか? よろしくお願いいたします。

  • C#のプログラムでエラーが…

    プログラムを作ったのですが、どうしてもエラーが出てしまいます。この中でどこが間違っているのか、教えてください!!(>_<)文字数の都合で見にくいですが… namespace DrawTool { public class MyLine { // 線の太さを設定 int lineWidth; // 線の太さをクラス外から設定 public int LineWidth { set { lineWidth = value; } } // 線を構成する複数の点 ArrayList Points = new ArrayList(); Color lineColor; public MyLine(int x, int y) { Points.Add(new Point(x, y)); } // 線の色をMyLine クラス外から設定 public Color LineColor { set { lineColor = value; } } // 現在の点の数を返す public int Count { get { return Points.Count; } } // 点を追加 public void Add(int x, int y) { Points.Add(new Point(x, y)); } // 線を描く public void Draw(Graphics g) { // ペンの作成 Pen pen = new Pen(lineColor, lineWidth); pen.EndCap = LineCap.Round; for(int i=0; i<Points.Count - 1; i++) g.DrawLine(pen, (Point)Points[i], (Point)Points[i + 1]); // ペンを開放 pen.Dispose(); } // 直前の追加分だけを描く public void DrawLastSegment(Graphics g) { // 線の始点終点をとりだす Point p1 = (Point)Points[Points.Count - 2]; Point p2 = (Point)Points[Points.Count - 1]; Pen pen = new Pen(lineColor, lineWidth); pen.EndCap = LineCap.Round; // 始点から終点まで線を引く g.DrawLine(pen, p1, p2); pen.Dispose(); } } }

  • MATLAB初心者;プログラミングのエラーが直せない

    こんにちわ、先週からMATLABを学び始め、これからプログラムを作っていこうと思っているところです。以下のプログラムを作ろうとしているのですが、エラーが出てしまいます。似たようなプログラムがあったのでそれを修正して、自分で解答してみたのですがうまくいきません。 【課題】Quadratic equation x^2+b*x+c = 0 has two roots. They are given by r1 = (-b+sqrt(b^2-4*c))/2 and r2 = (-b-sqrt(b^2-4*c))/2. Fix the value of c at c=1, plot r1 and r2 as functions of b for b in [2,3]. Plot two curves in one figure. Use about 100 points to represent each curve. 【自分の解答例】 % % Plot f1(x) = (-x+sqrt(x^2-4))/2 and f2(x) = (-x-sqrt(x^2-4))/2 for x in [2,3] % clear; clf; % n=81; dx=8/(n-1); x=[-4:dx:4]; f1=(-x+sqrt(x^2-4))/2; f2=(-x-sqrt(x^2-4))/2; % plot(x,f1,'b-','linewidth',2.0) hold on plot(x,f2,'ko') axis([-4.0,4.0,-1.4,3.8]) set(gca,'xtick',[-4:1:4]) set(gca,'ytick',[-1:1:3]) set(gca,'fontsize',14) xlabel('x') ylabel('f(x)') h1=legend('f1(x)=(-x+sqrt(x^2-4))','f2(x)=(-x-sqrt(x^2-4))/2'); set(h1,'fontsize',12) % ??? Error using ==> mpower Matrix must be square. というエラーが出てしまいます。変数はあとでbに直すつもりですが、エラーの意味がわかりません。よろしくお願いします。

  • matlabできる方教えてください

    matlab初心者です。 入力信号(sin波)に階段波形をかけるプログラムをかきたいのですが、うまくいきません。 以下は、私がかいたプログラムです。 わかる方がいらっしゃいましたら回答宜しくお願いします。 clear all;close all; fs= 250; t_l=[0 1]; t=t_l(1)+1/fs:1/fs:t_l(2); X = sin(2*pi*2*t); Y = sin(2*pi*10*t); Z = stairs(X).*Y; figure stairs(t,Z)

  • 関数から構造体を返す一般的な手法は

    たとえば下のような平面上の点を表す構造体があって、 typedef struct { const int x; const int y; } Point; 2点間の中心を計算する関数を書くとします。 この場合、計算結果をどのように返せばよいでしょうか。 「ただ動けばよい」コードを書くことはできるのですが、 私が知りたいのは、どのような書き方が一般的かということです。 構造体の要素が const なので、 下のコードはコンパイルできません。 void center(Point* result, Point* p1, Point* p2) {  result->x = (p1->x + p2->x) / 2;  result->y = (p1->y + p2->y) / 2; } 新しいオブジェクトを作ってコピーする? void center(Point* result, Point* p1, Point* p2) {  Point p = { (p1->x + p2->x) / 2, (p1->y + p2->y) / 2 };  memcpy(result, &p, sizeof(Point)); } この例のような小さい構造体であれば、 オブジェクトをまるごとリターンしてもよい? Point center(Point* p1, Point* p2) {  Point p = { (p1->x + p2->x) / 2, (p1->y + p2->y) / 2 };  return p; } あるいは、そもそも構造体の要素を const にする手法は C言語では一般的でないのでしょうか? どうかご教授願います。

  • matlab計算について

    matlab独学で進めていますが、時間がないのと頭が足りないので 質問させていただきます。 p1=0.1; p2=2.663*10^6; D= 1:10:1000; A=(log(D)+12.7)/1.1; f(D)=(1/power((2*pi),0.5)*1.1*D)*exp(-0.5*power(A,2)); Y=(p/pash*4/3*pi*power((D/2),3))*f(D) plot(D,Y) X軸がD、Y軸がf(D)のグラフを作成したいです。 内部行列の次元は一致しなければなりません。 とエラーが出ます。このエラーの原因を教えてください。 間違いだらけかもしれませんが...ご指摘よろしくお願いします。

専門家に質問してみよう