2

OpenInventor ファイルを PCD ファイルに変換する小さなプログラムを作成しています。そのために、OpenInventor ファイルと JPEG 画像の 2 つのファイルを入力します。テクスチャ座標は、0.0 ~ 1.0 の浮動小数点値です。

OpenCVを使ってRGB値を抽出して10進数で返すのですが、以下の関数がうまく動かないようです...

float get_color(cv::Mat img, float x, float y) {

    int i = x*img.cols;
    int j = y*img.rows;

    unsigned char R = img.ptr<unsigned char>(j)[3*i];
    unsigned char G = img.ptr<unsigned char>(j)[3*i+1];
    unsigned char B = img.ptr<unsigned char>(j)[3*i+2];

    return  R*pow(16,4) +
            G*pow(16,2) +
            B;
}

で画像をロードします

 cv::imread("filename.jpg", CV_LOAD_IMAGE_COLOR).
4

2 に答える 2

1

32ビット整数として返すという意味ですか?

unsigned int get_color(cv::Mat img, float x, float y) 
{

    int i = x*img.cols;
    int j = y*img.rows;

    unsigned char R = img.ptr<unsigned char>(j)[3*i];
    unsigned char G = img.ptr<unsigned char>(j)[3*i+1];
    unsigned char B = img.ptr<unsigned char>(j)[3*i+2];

    return  (R << 16) |
            (G << 8) |
            B;
}

または、フロートとして返したい場合は、次のようにする必要があります。

struct FloatColour
{
    float r;
    float g;
    float b;
};

float get_color(cv::Mat img, float x, float y) 
{

    int i = x*img.cols;
    int j = y*img.rows;

    unsigned char R = img.ptr<unsigned char>(j)[3*i];
    unsigned char G = img.ptr<unsigned char>(j)[3*i+1];
    unsigned char B = img.ptr<unsigned char>(j)[3*i+2];

    FloatColour retCol;
    retCol.r = R / 255.0f;
    retCol.g = G / 255.0f;
    retCol.b = B / 255.0f;
    return retCol;
}
于 2012-07-22T19:09:21.640 に答える
1

PCLのヘッダー「point_types.hpp」(PCLバージョン:1.5.1)にあるコメントで、自分の質問に対する答えを見つけました。

歴史的な理由 (PCL は最初に ROS パッケージとして開発されました) により、RGB 情報は整数にパックされ、浮動小数点数にキャストされます。これは近い将来に削除したいと考えているものですが、それまでの間、次のコード スニペットは、PointXYZRGB 構造で RGB カラーをパックおよびアンパックするのに役立ちます。

uint8_t r = 255, g = 0, b = 0;
uint32_t rgb = ((uint32_t)r << 16 | (uint32_t)g << 8 | (uint32_t)b);
p.rgb = *reinterpret_cast<float*>(&rgb);

リファクタリングとその他のいくつかのバグ修正の後、関数は次のようになりました。

float get_color(cv::Mat img, float s, float t){

        int j = (1.0 - s)*(float)img.cols;
        int i = (1.0 - t)*(float)img.rows;

        uint8_t R = img.at<cv::Vec3b>(i,j)[2];
        uint8_t G = img.at<cv::Vec3b>(i,j)[1];
        uint8_t B = img.at<cv::Vec3b>(i,j)[0];

        uint32_t rgb_32 = ((uint32_t)R << 16 | (uint32_t)G << 8 | (uint32_t)B);

        return *reinterpret_cast<float*>(&rgb_32);
}
于 2012-07-23T12:53:37.283 に答える