首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >openvino FormatReader vs cv::Mat image = cv::imdecode

openvino FormatReader vs cv::Mat image = cv::imdecode
EN

Stack Overflow用户
提问于 2020-07-14 19:52:52
回答 1查看 413关注 0票数 0

我正在尝试将c++ object_detection_ssd示例转换为dll库,以便我可以在我的c#应用程序中使用它。

下面是我的代码c++导出函数的代码

代码语言:javascript
复制
__declspec(dllexport) void Classify_Image(unsigned char* img_pointer, long data_len,
    char* out_result, int length_of_out_result, int top_n_results)
{
    
    std::vector<unsigned char> inputImageBytes(img_pointer, img_pointer + data_len);
    cv::Mat image = cv::imdecode(inputImageBytes,cv::IMREAD_COLOR);
    //cv::imwrite("lala.jpg", image);
    
    if (inputInfo == nullptr) {
        initialize();
    }

    // --------------------------- 8. Create infer request -------------------------------------------------
            //slog::info << "Create infer request" << slog::endl;
    InferRequest infer_request = executable_network.CreateInferRequest();
    // -----------------------------------------------------------------------------------------------------

    std::vector<std::shared_ptr<unsigned char>> imagesData, originalImagesData;
    std::vector<size_t> imageWidths, imageHeights;
    //FormatReader::ReaderPtr reader("C:\\Users\\Sam\\Desktop\\la.jpg");
    cv::Mat dst;

    cv::resize(image, dst, cv::Size(400, 225));
    cv::imwrite("lala_m.jpg", dst);
    //std::shared_ptr<unsigned char> originalData(image.data);
    std::shared_ptr<unsigned char> originalData(image.data);

    std::shared_ptr<unsigned char> data1(dst.data);
    //
    originalImagesData.push_back(originalData);
    imagesData.push_back(data1);
    imageWidths.push_back(1280);
    imageHeights.push_back(720);

    if (imagesData.empty()) throw std::logic_error("Valid input images were not found!");

    size_t batchSize = network.getBatchSize();
    
    if (batchSize != imagesData.size()) {
        slog::warn << "Number of images " + std::to_string(imagesData.size()) + \
            " doesn't match batch size " + std::to_string(batchSize) << slog::endl;
        batchSize = std::min(batchSize, imagesData.size());
        slog::warn << "Number of images to be processed is " << std::to_string(batchSize) << slog::endl;
    }
    
    ///** Creating input blob **/
    Blob::Ptr imageInput = infer_request.GetBlob(imageInputName);
    
    ///** Filling input tensor with images. First b channel, then g and r channels **/
    MemoryBlob::Ptr mimage = as<MemoryBlob>(imageInput);
    if (!mimage) {
        slog::err << "We expect image blob to be inherited from MemoryBlob, but by fact we were not able "
            "to cast imageInput to MemoryBlob" << slog::endl;
        return;
    }
    
    //// locked memory holder should be alive all time while access to its buffer happens
    auto minputHolder = mimage->wmap();
    size_t num_channels = mimage->getTensorDesc().getDims()[1];
    size_t image_size = mimage->getTensorDesc().getDims()[3] * mimage->getTensorDesc().getDims()[2];

    unsigned char *data = minputHolder.as<unsigned char *>();

    /** Iterate over all input images **/
    for (size_t image_id = 0; image_id < std::min(imagesData.size(), batchSize); ++image_id) {
        /** Iterate over all pixel in image (b,g,r) **/
        for (size_t pid = 0; pid < image_size; pid++) {
            /** Iterate over all channels **/
            for (size_t ch = 0; ch < num_channels; ++ch) {
                /**          [images stride + channels stride + pixel id ] all in bytes            **/
                data[image_id * image_size * num_channels + ch * image_size + pid] = imagesData.at(image_id).get()[pid*num_channels + ch];
            }
        }
    }

    if (imInfoInputName != "") {
        Blob::Ptr input2 = infer_request.GetBlob(imInfoInputName);
        auto imInfoDim = inputsInfo.find(imInfoInputName)->second->getTensorDesc().getDims()[1];

        /** Fill input tensor with values **/
        MemoryBlob::Ptr minput2 = as<MemoryBlob>(input2);
        if (!minput2) {
            slog::err << "We expect input2 blob to be inherited from MemoryBlob, but by fact we were not able "
                "to cast input2 to MemoryBlob" << slog::endl;
            return;
        }
        // locked memory holder should be alive all time while access to its buffer happens
        auto minput2Holder = minput2->wmap();
        float *p = minput2Holder.as<PrecisionTrait<Precision::FP32>::value_type *>();

        for (size_t image_id = 0; image_id < std::min(imagesData.size(), batchSize); ++image_id) {
            p[image_id * imInfoDim + 0] = static_cast<float>(inputsInfo[imageInputName]->getTensorDesc().getDims()[2]);
            p[image_id * imInfoDim + 1] = static_cast<float>(inputsInfo[imageInputName]->getTensorDesc().getDims()[3]);
            for (size_t k = 2; k < imInfoDim; k++) {
                p[image_id * imInfoDim + k] = 1.0f;  // all scale factors are set to 1.0
            }
        }
    }
    // -----------------------------------------------------------------------------------------------------

    // --------------------------- 10. Do inference ---------------------------------------------------------
    slog::info << "Start inference" << slog::endl;
    infer_request.Infer();
    // -----------------------------------------------------------------------------------------------------

    // --------------------------- 11. Process output -------------------------------------------------------
    slog::info << "Processing output blobs" << slog::endl;

    const Blob::Ptr output_blob = infer_request.GetBlob(outputName);
    MemoryBlob::CPtr moutput = as<MemoryBlob>(output_blob);
    if (!moutput) {
        throw std::logic_error("We expect output to be inherited from MemoryBlob, "
            "but by fact we were not able to cast output to MemoryBlob");
    }
    // locked memory holder should be alive all time while access to its buffer happens
    auto moutputHolder = moutput->rmap();
    const float *detection = moutputHolder.as<const PrecisionTrait<Precision::FP32>::value_type *>();

    std::vector<std::vector<int> > boxes(batchSize);
    std::vector<std::vector<int> > classes(batchSize);

    ///* Each detection has image_id that denotes processed image */
    std::string result = "OB_DATA=";
    int num_detect = 0;
    
    for (int curProposal = 0; curProposal < maxProposalCount; curProposal++) {
        auto image_id = static_cast<int>(detection[curProposal * objectSize + 0]);
        if (image_id < 0 ) {
            slog::info << "ends with break "<<slog::endl;
            break;
        }

        float confidence = detection[curProposal * objectSize + 2];
        auto label = static_cast<int>(detection[curProposal * objectSize + 1]);
        auto xmin = static_cast<int>(detection[curProposal * objectSize + 3] * imageWidths[image_id]);
        auto ymin = static_cast<int>(detection[curProposal * objectSize + 4] * imageHeights[image_id]);
        auto xmax = static_cast<int>(detection[curProposal * objectSize + 5] * imageWidths[image_id]);
        auto ymax = static_cast<int>(detection[curProposal * objectSize + 6] * imageHeights[image_id]);

        std::cout << "[" << curProposal << "," << label << "] element, prob = " << confidence <<
                "    (" << xmin << "," << ymin << ")-(" << xmax << "," << ymax << ")" << " batch id : " << image_id;

        if (confidence > 0.5) {
            num_detect += 1;
            result += std::to_string(confidence);
            
            result += ","+ std::to_string(label);
            result += "," + std::to_string(xmin);
            result += "," + std::to_string(ymin);
            result += "," + std::to_string(xmax);
            result += "," + std::to_string(ymax);
            
            /** Drawing only objects with >50% probability **/
            classes[image_id].push_back(label);
            boxes[image_id].push_back(xmin);
            boxes[image_id].push_back(ymin);
            boxes[image_id].push_back(xmax - xmin);
            boxes[image_id].push_back(ymax - ymin);
            //std::cout << " WILL BE PRINTED!";
            /*std::cout << std::endl;*/
            //slog::info << " add prediction" << slog::endl;
        }
        result += ";";
        std::cout << std::endl;
    }
    
    data1.reset();
    originalData.reset();
    
    //dst.release();
    //image.release();
    

    length_of_out_result = (int)result.size();
    
    std::copy(result.begin(), result.end(), out_result);
    out_result[std::min(length_of_out_result - 1, (int)result.size())] = 0;
            std::cout << "end code"<<std::endl;
    
}

}

在上面的代码中,我试图解码我从c#发送到opencv mat的字节数组,并在mat对象上运行推断,所以当我从c#调用这个函数时,它工作得很好,但在打印"end code“行之后,它在我的c#应用程序中出现错误,下面是我在c#中的代码,我的c#应用程序不能打印Console.WriteLine(”调用后“);在visual studio输出中,我可以看到c++函数打印的最后一行是"end code”

代码语言:javascript
复制
[DllImport("object_detection_sample_ssd.dll", CallingConvention = CallingConvention.Cdecl)]
    static extern void Classify_Image(byte[] img, long data_len, StringBuilder out_result, int out_result_length, int top_n_results = 2);

    private void button3_Click(object sender, EventArgs e)
    {
        byte[] result = new byte[200];
        Image img = Image.FromFile(@"C:\Users\Sam\Desktop\la.jpg");
        ImageFormat fmt = new ImageFormat(img.RawFormat.Guid);
        var imageCodecInfo = ImageCodecInfo.GetImageEncoders().FirstOrDefault(codec => codec.FormatID == img.RawFormat.Guid);
        //this is for situations, where the image is not read from disk, and is stored in the memort(e.g. image comes from a camera or snapshot)
        if (imageCodecInfo == null)
        {
            fmt = ImageFormat.Jpeg;
        }
        //Image img = Image.FromFile(@"");
        using (MemoryStream ms = new MemoryStream())
        {
            img.Save(ms, fmt);
            byte[] image_byte_array = ms.ToArray();
            int len_result=300;

            int STRING_MAX_LENGTH1 = 300;
            StringBuilder str1 = new StringBuilder(STRING_MAX_LENGTH1);

            Classify_Image(image_byte_array, ms.Length, str1, len_result, 2);
            Console.WriteLine("after call");
        }
        Console.WriteLine("even after using");
        Console.WriteLine("output ="+ ASCIIEncoding.ASCII.GetString(result));
        
    }

我不知道这有什么问题,在openvino工具包的原始示例中有一个FormatReader.h文件,用于从图像文件路径加载图像,我尝试过传递图像文件名并使用FormatReader作为原始文件,它工作了。FormatReader https://github.com/openvinotoolkit/openvino/tree/master/inference-engine/samples/common/format_reader

请帮帮我!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-07-22 18:40:12

我建议您参考Hello Classification C++示例,它从Mat加载图像以进行推理。可通过以下链接获得main.cpp文件:https://github.com/openvinotoolkit/openvino/blob/master/inference-engine/samples/hello_classification/main.cpp

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62894561

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档