0

2 つのフォルダー (それぞれ 1000 個のファイルを持つ) の画像ファイルをいくつかのロジックと比較するプログラムを作成しました(この SO の質問を参照)

実行中、900 枚の画像まで正常に比較されますが、Use of uninitialized value within @tfiles2 in concatenation (.) or string at C:\dropbox\Image_Compare\image_magick.pl line 55(#3) のようなエラーが発生します。すると、 のようなポップアップエラーが出るPerl Command Line Interpreter has stopped workingので、プログラムを閉じます。

私のコードは次のとおりです。

#!/usr/bin/perl
 use Image::Magick;
 no warnings 'uninitialized';
 use warnings;
 use diagnostics;
#use strict;
 use List::Util qw(first);

    my $directory1="C:/dropbox/Image_Compare/folder1";
    opendir(DIR, $directory1) or die "couldn't open $directory1: $!\n";
    my @files1 = grep { (!/^\./) && -f "$directory1/$_" } readdir(DIR);
    closedir DIR;
    print @files1;
    print 'end of files1';
    my $directory2="C:/dropbox/Image_Compare/folder2";
    opendir(DIR, $directory2) or die "couldn't open $directory2: $!\n";
    my @files2= grep { (!/^\./) && -f "$directory2/$_" } readdir(DIR);
    closedir DIR;
    print @files2;
    print 'end of files2';
    print $files1[0];
    foreach my $fils2 (@files2)
    {
        $g1 = Image::Magick->new;
        $g2 = Image::Magick->new;
        $temp1 = $g1->Read( filename=>"C:/dropbox/Image_Compare/folder1/".$files1[0].""); 
        $temp1 = $g2->Read( filename=>"C:/dropbox/Image_Compare/folder2/".$fils2."");
        $g3 = $g1->Compare( image=>$g2, metric=>'AE' ); # compare
        $error1 = $g3->Get( 'error' );
        #print $error1;
        if ($error1 == '0') 
        {
            print "Matching image is:"; 
            print $fils2 . "\n"; 
            my $tdirectory2="C:/dropbox/Image_Compare/folder2";
            opendir(DIR, $tdirectory2) or die "couldn't open $directory2: $!\n";
            my @tfiles2 = grep { (!/^\./) && -f "$tdirectory2/$_" } readdir(DIR);
            closedir DIR;
            #my $index = firstidx { $_ eq'"' .$fils2.'"' } @tfiles2;
            my $index = first { $tfiles2[$_] eq $fils2} 0..$#tfiles2;
            #print $fils2;
            print $index;
            my $i=0;
            foreach my $fils1 (@files1)
            {
                print 'ganesh';
                print $files1[$i];
                print $tfiles2[$index];
                print 'gowtham'; print "<br />";
                #print @tfiles2;
                $g4 = Image::Magick->new;
                $g5 = Image::Magick->new;
                $temp2 = $g4->Read( filename=>"C:/dropbox/Image_Compare/folder1/".$files1[$i].""); 
                $temp2 = $g5->Read( filename=>"C:/dropbox/Image_Compare/folder2/".$tfiles2[$index]."");
                $g6 = $g4->Compare( image=>$g5, metric=>'AE' ); # compare
                $error2 = $g6->Get( 'error' );
                $i++;
                $index++;
                if ($error2 == '0') {}
                else {print "Image not matching:"; print $tfiles2[$index]; last;}
                #if ($i == '800') {last;}


            }
            last
        }
    }

私が間違いを犯している場所で、誰でも助けてください。

フォルダ 1 のファイル名: 0025.bmp から 1051.bmp。

フォルダ 2 のファイル名: 0000.bmp ~ 1008.bmp。

ありがとうガネーシャ

4

1 に答える 1

2

問題のある行がどれかはわかりませんが、次のいずれかが候補になる可能性があります。

$temp2 = $g5->Read( filename=>"C:/dropbox/Image_Compare/folder2/".$tfiles2[$index]."");

また

else {print "Image not matching:"; print $tfiles2[$index]; last;}

$index配列の境界内にあるかどうかにかかわらず、インクリメントすることに注意してください。$index > $#tfilesループを中断する条件をチェックしません。

のように長さを出力して、両方の入力配列に >> 900 要素が含まれていることを主張したい場合がありますprint "length: ", scalar @array, "\n";

undefined配列内の要素の定義をテストすることで、エラーが実際に発生するインデックスをテストできます。

if (not defined $tfiles[$index] or not defined $files1[$i]) {
   die "There was an undefined element at index=$index, i=$i";
}

$iしかし、繰り返しになりますが、 との間のオフセット$indexは一定であるため (私の回答で述べたように)、実際に 2 つの変数を運ぶ必要はありません。

単純な比較サブルーチンを使用すると、コードが読みやすくなり、デバッグが容易になります (手続き型プログラミングを参照)。

# return true if matching, false otherwise.
sub compare_images {
   my ($file1, $file2) = @_;
   my $image1 = Image::Magick->new;
   $image1->Read(filename => $file1);
   my $image2 = Image::Magick->new;
   $image2->Read(filename => $file2);
   my $result = $image1->Compare(image => $image2, metric => 'AE')->Get('error');
   # free memory
   undef $image1;
   undef $image2;
   return 0 == $result;
}

のように呼ばれる

my $image_root = "C:/dropbox/Image_Compare";
my ($folder1, $folder2) = qw(folder1 folder2);
unless (compare_images("$image_root/$folder1/$files1[$i]", 
                       "$image_root/$folder2/$tfiles[$index]")) {
   print "Images not matching at index=$index, i=$i\n";
   print "filename: $tfiles[$index]\n";
   last;
}

次のようにディレクトリを読むことができます

sub get_images_from_dir {
   my ($dirname) = @_;
   -d $dirname or die qq(The path "$dirname" doesn't point to a directory!);
   opendir my $dir => $dirname or die qq(Can't open "$dirname": $!);
   my @files = grep {!/^\./ and -f "$dirname/$_"} readdir $dir;
   closedir $dir;
   unless (@files) { die qq(There were no interesting files in "$dirname".) }
   return @files;
}

このような手順により、コードが読みやすくなり、チェックを挿入しやすくなります。

于 2012-12-18T13:52:42.053 に答える