1

画像 green.jpg を (0,0) から赤で塗りつぶしたいと考えています。これを C++ で実行してみました (Python は再帰が遅いため)、ピクセルを取得および設定するためのイメージング ライブラリとして CImg を使用しました。これが私のプログラムです。

#include <iostream>
#include <tuple>
#include <vector>
#include "CImg.h"

using namespace cimg_library;

int main()
{
    CImg<unsigned char> im("green.jpg");
    int l = im.width();
    int w = im.height();
    int x = 0;
    int y = 0;

    auto newcol = std::make_tuple(255,0,0);
    int R = im(x,y,0,0);
    int G = im(x,y,0,1);
    int B = im(x,y,0,2);
    auto oldcol = std::make_tuple(R,G,B);

    std::vector<std::tuple<int,int>> edge = {std::make_tuple(x,y)};

    while (edge.size() != 0)
    {
    std::vector<std::tuple<int,int>> newedge;
        for (int e = 0; e < edge.size(); e++)
        {
            int a = std::get<0>(edge[e]);
            int b = std::get<1>(edge[e]);

            if (0 <= a <= l && 0 <= b <= w) 
            {
                auto currcol = std::make_tuple(im(a,b,0,0),im(a,b,0,1),im(a,b,0,2));

                if (currcol == oldcol)
                {
                        im(a,b,0,0) = std::get<0>(newcol);
                        im(a,b,0,1) = std::get<1>(newcol);
                        im(a,b,0,2) = std::get<2>(newcol);
                        newedge.push_back(std::make_tuple(a-1,b));
                        newedge.push_back(std::make_tuple(a+1,b));
                        newedge.push_back(std::make_tuple(a,b+1));
                        newedge.push_back(std::make_tuple(a,b-1));          
                }
            }
        }
        edge = newedge;
    }

    im.save("done.jpg");    
    return 0;
}

ただし、原因が見つからない SegFault が発生し続けます。gdb を使用してプログラムをデバッグしようとしましたが、次のように返されます。

Program received signal SIGSEGV, Segmentation fault.
0x000000000040b67c in std::_Head_base<2ul, unsigned char, false>::_Head_base<unsigned char&, void> (this=0x7fffffffdd10, 
__h=@0x8000f7f8c0bf: <error reading variable>) at /usr/include/c++/4.8/tuple:140

これは明らかにタプルヘッダーファイルにあります。SegFault の原因と修正方法を教えてください。ありがとうございました。

編集: スタック トレースを追加:

(gdb) bt
#0  0x000000000040b67c in std::_Head_base<2ul, unsigned char, false>::_Head_base<unsigned char&, void> (this=0x7fffffffdd10, 
    __h=@0x1006b87d1: <error reading variable>) at /usr/include/c++/4.8/tuple:140
#1  0x000000000040b6c2 in std::_Tuple_impl<2ul, unsigned char>::_Tuple_impl<unsigned char&, , void>(unsigned char&) (this=0x7fffffffdd10, 
    __head=@0x1006b87d1: <error reading variable>) at /usr/include/c++/4.8/tuple:262
#2  0x000000000040b71e in std::_Tuple_impl<1ul, unsigned char, unsigned char>::_Tuple_impl<unsigned char&, unsigned char&, void> (
    this=0x7fffffffdd10, __head=@0x1006b86f0: <error reading variable>) at /usr/include/c++/4.8/tuple:262
#3  0x000000000040b7b1 in std::_Tuple_impl<0ul, unsigned char, unsigned char, unsigned char>::_Tuple_impl<unsigned char&, unsigned char&, unsigned char&, void> (this=0x7fffffffdd10, __head=@0x1006b860f: <error reading variable>) at /usr/include/c++/4.8/tuple:262
#4  0x000000000040b832 in std::tuple<unsigned char, unsigned char, unsigned char>::tuple<unsigned char&, unsigned char&, unsigned char&, void> (
this=0x7fffffffdd10) at /usr/include/c++/4.8/tuple:405
#5  0x000000000040b895 in std::make_tuple<unsigned char&, unsigned char&, unsigned char&> () at /usr/include/c++/4.8/tuple:862
#6  0x0000000000402e5d in main () at fill.cpp:34
4

1 に答える 1

1

私は自分の問題を修正しました。gdb で、変数の 1 つである a が -1 に等しいことがわかりました。これはイメージの範囲外であり、メモリの問題とセグメンテーション違反を引き起こしています。if (0 <= a <= l && 0 <= b <= w)これをキャッチするはずでしたがa <= b <= c、C++ では正しく動作しないようです。だから私はそれをに変更しました、if (0 <= a && a <= l && 0 <= b && b <= w)そしてそれはうまくいきました。

ご支援いただきありがとうございます。

于 2014-01-26T04:07:43.920 に答える