IplImage to vector <uint8_t>

goG*_*Gud -2 c++ opencv

我怎样才能转换IplImagevector<uint8_t>.如果我将图像路径发送到以下功能,我可以转换它:

bool faceImg::load_file (const string &path, vector<uint8_t> &data)
{
    data.clear();

    std::ifstream is(path.c_str(), std::ios::in | std::ios::binary);
    if (!is.is_open())
        return false;

    is.seekg(0, is.end);
    size_t len = (size_t)is.tellg();
    is.seekg(0, is.beg);
    data.resize(len);
    is.read((char*)data.data(), len);

    return true;
}
Run Code Online (Sandbox Code Playgroud)

但是我想从相机捕获中重写IplImage的功能:

bool faceImg::load_image(IplImage *image, vector<uint8_t> &data)
{

}
Run Code Online (Sandbox Code Playgroud)

Mic*_*cka 7

这是你想要的功能.你可以优化它,类似于maxint提供的版本(但重塑可能会改变输入IplImage?!?).

该功能应适用于任意数量的通道,但它采用8位类型(例如8位灰度图像或24位BGR图像).

这是我的功能:

// you dont need this typedef!
typedef unsigned char uint8_t ;

// probably not the fastest way ;)
// returns a vector with this ordering:
// x=0; y=0; Blue Channel value
// x=0; y=0; Green Channel value
// x=0; y=0; Red Channel value
// x=1; y=0; Blue Channel value
// ...
bool load_image(IplImage *image, std::vector<uint8_t> &data)
{
    if(image->depth != 8) return false;

    // only allocate the memory once
    data.reserve(image->width*image->height* image->nChannels);

    unsigned char * imgPtr = (unsigned char*) image->imageData;

    for(unsigned int y=0; y<image->height; ++y)
        for(unsigned int x=0; x<image->width; ++x)
            for(unsigned int c=0; c<image->nChannels; ++c)
            {
                unsigned char * valuePtr = imgPtr + y*image->widthStep + x*image->nChannels + c;
                data.push_back(*valuePtr);
            }

    return true;
}
Run Code Online (Sandbox Code Playgroud)

我用这个函数来测试:

int main()
{
    //cv::Mat input = cv::imread("../inputData/Lenna.png", CV_LOAD_IMAGE_GRAYSCALE);
    cv::Mat input = cv::imread("../inputData/Lenna.png");

    // your IplImage, this one is 24 bit BGR format
    IplImage * yourImage = &(IplImage)input;

    // your vector
    std::vector<uint8_t> data;

    // your function call to load that image to a vector
    load_image(yourImage, data);

    // unit test: check whether pixel in cv::Mat are the same as the ones in the vector
    for(unsigned int j=0; j<input.rows; ++j)
        for(unsigned int i=0; i<input.cols; ++i)
        {
            if(input.channels() == 3)
            {
                cv::Vec3b pixel = input.at<cv::Vec3b>(j,i);
                for(unsigned int c=0; c<input.channels(); ++c)
                {
                    if(pixel[c] != data[input.channels()*j*input.rows + input.channels()*i +c])
                        std::cout << "different values at: (" << i << "," << j << "): " << (int)pixel[c] << " vs " << (int)data[input.channels()*j*input.rows + input.channels()*i +c] << std::endl;
                }
            }
            else if(input.channels() == 1)
            {
                unsigned char pixel = input.at<unsigned char>(j,i);
                for(unsigned int c=0; c<input.channels(); ++c)
                {
                    if(pixel != data[input.channels()*j*input.rows + input.channels()*i +c])
                        std::cout << "different values at: (" << i << "," << j << "): " << (int)pixel << " vs " << (int)data[input.channels()*j*input.rows + input.channels()*i +c] << std::endl;
                }
            }
        }


    cvNamedWindow("IplImage");
    cvShowImage("IplImage", yourImage);


    cv::imshow("input", input);
    cv::waitKey(0);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)