- PR -

背景差分法について

投稿者投稿内容
ぶぅぶぅ
常連さん
会議室デビュー日: 2005/10/19
投稿数: 20
投稿日時: 2005-12-14 19:04
お久しぶりです。毎回勉強させていただいています。
まだまだJava勉強中で分からないことばかりですが、助けてください。
たくさんある画像(似たような画像)があって、その全ての画像の画素数の平均をとったのち、それを背景画像(a)として登録。

(a)と全ての画像を背景差分をしたのち、値の差が大きい画像から出していくというものをしたいと思っています。
そこで、まずは2枚の画像でやってみようと思いました。
Image型で2枚の画像(背景画像img1と何らかのものが写った画像img2)を読み込み、それを背景差分を取ろうと…
がしかし、できません。
サンプルプログラムみたいなものがあれば誰かよろしくお願いします!

すみません、文章が変で読みにくいと思いますがお願いします。
Kazuki
ぬし
会議室デビュー日: 2004/10/13
投稿数: 298
投稿日時: 2005-12-14 20:20
引用:

ぶぅぶぅさんの書き込み (2005-12-14 19:04) より:
そこで、まずは2枚の画像でやってみようと思いました。
Image型で2枚の画像(背景画像img1と何らかのものが写った画像img2)を読み込み、それを背景差分を取ろうと…
がしかし、できません。


何処がわからないのかわかりません。
画像の読み込みならImageIOクラスあたりを使うといけそうです。

引用:

すみません、文章が変で読みにくいと思いますがお願いします。


そう思うならプレビューして読んでみて書き直すのがいいと思いますよ。
ぶぅぶぅ
常連さん
会議室デビュー日: 2005/10/19
投稿数: 20
投稿日時: 2005-12-15 11:10
書き込みありがとうございます!
私が書いたソースです。
今は、label1と2に元画像2枚を読み込み、label3に差分した結果を表示させようとしています。差分を取っている部分がうまくいっていないようなので、おかしいところなどを直していただけませんか?
コメント文にしていた場所は消しているから変になっているかもしれませんが…

public class HaikeiSabun{

private static Image img01,img02;

private static Image isabun;

int pixelsBefore[] = null;
int pixelsAfter[] = null;

JLabel label1 = new JLabel();
JLabel label2 = new JLabel();
JLabel label3 = new JLabel();


public static void main(String[] args) {
new HaikeiSabun();
}

public HaikeiSabun(){
JFrame frame = new JFrame("Test");
frame.setBounds(0,0,700,600);
ControlPanel cp = new ControlPanel();

JPanel panel = new JPanel();
panel.setLayout(null);

label1.setBounds(10,10,320,240);
label2.setBounds(350,10,320,240);
label3.setBounds(10,270,320,240);
cp.setBounds(350,270,150,140);

Toolkit tk = Toolkit.getDefaultToolkit();
img01 = tk.getImage("./iii/sample12.jpg");
img02 = tk.getImage("./iii/sample11.jpg");
label1.setIcon(new ImageIcon(img01));
label2.setIcon(new ImageIcon(img02));

panel.add(label1);
panel.add(label2);
panel.add(label3);
panel.add(cp);

frame.getContentPane().add(panel);
frame.setVisible(true);
}
public class ControlPanel extends JPanel implements ActionListener {

JButton sabun = new JButton(" 差分 ");


public ControlPanel(){
setLayout(new GridLayout(3,1));

add(sabun);

sabun.addActionListener(this);

}
public void actionPerformed(ActionEvent evt) {
if ((JButton) (evt.getSource()) == sabun) {
isabun = HSabun(img01,img02);
label3.setIcon(new ImageIcon(isabun));
     }

}
/**
* @param img01
* @param img02
* @return
*/
private Image HSabun(Image img01, Image img02) {
// TODO 自動生成されたメソッド・スタブ
int width = 320;
int height = 240;
int size = width * height;
int k=0;

int[] pixelsBefore = new int[size];
int[] pixelsAfter = new int[size];
int[] img_sabun = new int[size];


PixelGrabber pgb = new PixelGrabber(img01,0,0,width,height,pixelsBefore,0,width);
PixelGrabber pga = new PixelGrabber(img02,0,0,width,height,pixelsAfter,0,width);
try{
pgb.grabPixels(); //画像imgを配列pixels[]に読み込む
pga.grabPixels();
}catch(InterruptedException e){}

for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {

k = pixelsBefore[y * width + x] - pixelsAfter[y * width + x];

if (k != 0) {
k = 1;
}
img_sabun[y * width + x] = k;
k = 0;
}
}
isabun = createImage(new MemoryImageSource(width,height,img_sabun,0,width));

return isabun;
}


}
くれよん
ベテラン
会議室デビュー日: 2005/04/28
投稿数: 74
投稿日時: 2005-12-16 00:59
こんにちわ。以下のような、部分がプログラム中にありました。
if (k != 0) {
k = 1;
}
img_sabun[y * width + x] = k;
k = 0;
}

それを、次のように直してみてください。
if (k != 0) {
img_sabun[y * width + x] = Color.black.getRGB();
}else{
img_sabun[y * width + x] = Color.white.getRGB();
}

PixelGrabberでint型配列に取り込んだ情報はRGBの値です(?)
以下のコードでRGB値が取り出せます。
rgb = pixels[i];
red = ((rgb >> 16 ) & 0xff);
green = ((rgb >> 8 ) & 0xff);
blue = ( rgb & 0xff);

また、R、G、Bを、配列に格納する場合は、以下のようにします。
pixels[i] = (0xff000000 | Rad << 16 | green << 8 | blue);

説明が下手ですいません。


[ メッセージ編集済み 編集者: ジュン 編集日時 2005-12-16 01:02 ]

[ メッセージ編集済み 編集者: ジュン 編集日時 2005-12-16 01:04 ]
ぶぅぶぅ
常連さん
会議室デビュー日: 2005/10/19
投稿数: 20
投稿日時: 2005-12-16 14:38
お返事ありがとうございます。以下のように変更してみたんですが、どうもうまくいきません。PixelGrabberでint型配列に取り込んだ情報は、例えば-9408400などの数字でした。今回ジュンさんが返答してくれたように、RGBの値を入れてみたんですが何かおかしいです。。私のやり方がダメだって言うことは分かるんですが、どこが悪いのかが分かりません。すみませんが、訂正のほどよろしくお願いします!
ちなみに、2つ読み込んだ画像img01,img02はグレイスケール画像です。

private Image HSabun(Image img01, Image img02) {
int height = 240;
int size = width * height;
int k=0,d,rgb1,rgb2;
int red1 = 0,green1 = 0, blue1 = 0;
int red2 = 0,green2 = 0, blue2 = 0;
Color color;

int[] pixelsBefore=new int[size];
int[] pixelsAfter=new int[size];
int[] img_sabun = new int[size];

for(int i=0;i<size;i++){
pixelsBefore[i] = 0;
pixelsAfter[i] = 0;
}

PixelGrabber pgb = new PixelGrabber(img01,0,0,width,height,pixelsBefore,0,width);
PixelGrabber pga = new PixelGrabber(img02,0,0,width,height,pixelsAfter,0,width);
try{
pgb.grabPixels(); //画像imgを配列pixels[]に読み込む
pga.grabPixels();
}catch(InterruptedException e){}

for(int i=0;i<size; i++){
rgb1 = pixelsBefore[i];
red1 = ((rgb1 >> 16 ) & 0xff);
green1 = ((rgb1 >> 8 ) & 0xff);
blue1 = ( rgb1 & 0xff);

rgb2 = pixelsAfter[i];
red2 = ((rgb2 >> 16 ) & 0xff);
green2 = ((rgb2 >> 8 ) & 0xff);
blue2 = ( rgb2 & 0xff);

//R、G、Bを、配列に格納する
pixelsBefore[i] = (0xff000000 | red1 << 16 | green1 << 8 | blue1);
pixelsAfter[i] = (0xff000000 | red2 << 16 | green2 << 8 | blue2);

k = pixelsBefore[i] - pixelsAfter[i];
System.out.println(k);
color = new Color(k);
d = color.getBlue();
if (k != 0) {
img_sabun[i] = Color.black.getRGB();
}else{
img_sabun[i] = Color.white.getRGB();
}

color=new Color(d,d,d);
img_sabun[i]=color.getRGB();
}

isabun = createImage(new MemoryImageSource(width,height,img_sabun,0,width));


return isabun;
}

[ メッセージ編集済み 編集者: ぶぅぶぅ 編集日時 2005-12-16 14:58 ]
くれよん
ベテラン
会議室デビュー日: 2005/04/28
投稿数: 74
投稿日時: 2005-12-16 17:34
私がPixelGrabberの説明をしたせいで、RGBごとに差分を計算すると思われたかもしれませんが、そうではありません。最初のプログラムで配列に格納していたKの値が、K=1やK=0となっていたため、参考程度にPixelGrabberの説明を載せただけです。

以下のプログラムで、うまく動くはずです

public class HaikeiSabun{
private static Image img01,img02;
private static Image isabun;

int pixelsBefore[] = null;
int pixelsAfter[] = null;

JLabel label1 = new JLabel();
JLabel label2 = new JLabel();
JLabel label3 = new JLabel();


public static void main(String[] args) {
new HaikeiSabun();
}

public HaikeiSabun(){
JFrame frame = new JFrame("Test");
frame.setBounds(0,0,700,600);
ControlPanel cp = new ControlPanel();

JPanel panel = new JPanel();
panel.setLayout(null);

label1.setBounds(10,10,320,240);
label2.setBounds(350,10,320,240);
label3.setBounds(10,270,320,240);
cp.setBounds(350,270,150,140);

Toolkit tk = Toolkit.getDefaultToolkit();
img01 = tk.getImage("画像1");
img02 = tk.getImage("画像2");
label1.setIcon(new ImageIcon(img01));
label2.setIcon(new ImageIcon(img02));

panel.add(label1);
panel.add(label2);
panel.add(label3);
panel.add(cp);

frame.getContentPane().add(panel);
frame.setVisible(true);
}

class ControlPanel extends JPanel implements ActionListener {
JButton sabun = new JButton(" 差分 ");
public ControlPanel(){
setLayout(new GridLayout(3,1));
add(sabun);
sabun.addActionListener(this);
}

public void actionPerformed(ActionEvent evt) {
if ((JButton) (evt.getSource()) == sabun) {
isabun = HSabun(img01,img02);
label3.setIcon(new ImageIcon(isabun));
}
}

/**
* @param img01
* @param img02
* @return
*/
private Image HSabun(Image img01, Image img02) {
int width = 320;
int height = 240;
int size = width * height;
int k=0;

int[] pixelsBefore = new int[size];
int[] pixelsAfter = new int[size];
int[] img_sabun = new int[size];


PixelGrabber pgb = new PixelGrabber(img01,0,0,width,height,pixelsBefore,0,width);
PixelGrabber pga = new PixelGrabber(img02,0,0,width,height,pixelsAfter,0,width);
try{
pgb.grabPixels(); //画像imgを配列pixels[]に読み込む
pga.grabPixels();
}catch(InterruptedException e){
}

for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
if (pixelsBefore[y * width + x] == pixelsAfter[y * width + x]) {
//img_sabun[y * width + x] = (0xff000000 | 0 << 16 | 0 << 8 | 0)
img_sabun[y * width + x] = Color.white.getRGB();
}else{
//img_sabun[y * width + x] = (0xff000000 | 255 << 16 | 255 << 8 | 255)
img_sabun[y * width + x] = Color.black.getRGB();
}
}
}
isabun = createImage(new MemoryImageSource(width,height,img_sabun,0,width));

return isabun;
}
}
}
ぶぅぶぅ
常連さん
会議室デビュー日: 2005/10/19
投稿数: 20
投稿日時: 2005-12-16 23:27
返答ありがとうございます。
>ジュンさん
そういうことだったんですね^^;
よく勉強しないままだったので勘違いをしてしまったようです↓

とりあえず、ジュンさんのソースをそのまま実行してみたところ、一応画像は表示されるのですが、うまく差分がとれていない模様です。ここにその画像を載せることができないのが残念>_<
用意した2枚の画像がダメなだけなんですかねぇ?他の画像でも試してみたいと思います。
ありがとうございます!
Kazuki
ぬし
会議室デビュー日: 2004/10/13
投稿数: 298
投稿日時: 2005-12-17 07:33
何がどううまくいってないのか言わないと…

スキルアップ/キャリアアップ(JOB@IT)