- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I created small application with OpenVINO which takes 3-channel image and apply to it neural net. NN was trained for segmentation and must find ellipses. But in output blob I see white ellipse and many noise pixels. Could anybody help me find an error?
In applied archive there are:
- TestOpVnn.cpp - main program (one file in MSVS project) - this file attached singly
- Neural net in IR format (zf_unet_224)
- Basic neural net in Keras format (h5+json)
- Input image (input.png)
- Expected output image (output.png)
- Output image which gave us OpenVINO program (output_image.bmp)
Images:
Input:
Expected output:
Real output:
My application code:
#include "pch.h" #include <iostream> #include <string> #include <vector> // Without next pragmas there are many warnings, how correctly fix them? #pragma warning(push) #pragma warning(disable:4251) #pragma warning(disable:4275) #include <inference_engine.hpp> #pragma warning(pop) #include <opencv2/opencv.hpp> template<class T> std::ostream & operator << (std::ostream &out, const std::vector<T> &vec) { out << "{ "; for (size_t i = 0; i + 1 < vec.size(); ++i) { out << vec << ", "; } if (!vec.empty()) { out << vec.back(); } out << " }"; return out; } namespace io_info { template<class T> void i_print_info(const T & i_info) { std::cout << " io_info->getPrecision() = " << i_info->getPrecision() << std::endl; std::cout << " io_info->getLayout () = " << i_info->getLayout() << std::endl; std::cout << " io_info->name () = " << i_info->name() << std::endl; std::cout << " io_info->dims = " << i_info->getTensorDesc().getDims() << std::endl; std::cout << std::endl; } } namespace OV_helper { /** * @brief Sets image data stored in cv::Mat object to a given Blob object. * @param orig_image - given cv::Mat object with an image data. * @param blob - Blob object which to be filled by an image data. * @param batchIndex - batch index of an image inside of the blob. */ template <typename T> void matU8ToBlob(const cv::Mat& orig_image, InferenceEngine::Blob::Ptr& blob, int batchIndex = 0) { InferenceEngine::SizeVector blobSize = blob->getTensorDesc().getDims(); const size_t width = blobSize[3]; const size_t height = blobSize[2]; const size_t channels = blobSize[1]; T* blob_data = blob->buffer().as<T*>(); cv::Mat resized_image(orig_image); if (static_cast<int>(width) != orig_image.size().width || static_cast<int>(height) != orig_image.size().height) { cv::resize(orig_image, resized_image, cv::Size(width, height)); } int batchOffset = batchIndex * width * height * channels; for (size_t c = 0; c < channels; c++) { for (size_t h = 0; h < height; h++) { for (size_t w = 0; w < width; w++) { blob_data[batchOffset + c * width * height + h * width + w] = resized_image.at<cv::Vec3b>(h, w); } } } } // Extracts 1-channel image from the FP32 blob cv::Mat blobFP32_to_img1ch(const InferenceEngine::Blob::Ptr &blob, int batchIndex = 0) { InferenceEngine::SizeVector blobSize = blob->getTensorDesc().getDims(); std::cout << " blobSize = " << blobSize << std::endl; const size_t width = blobSize[3]; const size_t height = blobSize[2]; const size_t channels = blobSize[1]; std::cout << " width = " << width << std::endl; std::cout << " height = " << height << std::endl; std::cout << " channels = " << channels << std::endl; if (channels != 1) { throw std::runtime_error("OV_helper::blobFP32_to_img1ch() : Invalid numbers of channels."); } cv::Mat img(height, width, CV_8UC1); float* blob_data = blob->buffer().as<float*>(); if ( static_cast<int>(width ) != img.size().width || static_cast<int>(height) != img.size().height) { throw std::runtime_error("OV_helper::blobFP32_to_img1ch() : Invalid img sizes."); } int batchOffset = batchIndex * width * height * channels; for (size_t c = 0; c < channels; c++) { for (size_t h = 0; h < height; h++) { for (size_t w = 0; w < width; w++) { img.at<uchar>(h, w) = 255 * blob_data[batchOffset + c * width * height + h * width + w]; } } } return img; } } // namespace OV_helper int main() { try { // Read model name std::string model_name; std::cin >> model_name; std::string model_xml = model_name + ".xml"; std::string model_bin = model_name + ".bin"; std::cout << std::endl << " net source = " << "[ " + model_xml + ", " + model_bin + " ]" << std::endl; // Read image name std::string image_name; std::cin >> image_name; cv::Mat1f frame = cv::imread(image_name, cv::IMREAD_GRAYSCALE); std::cout << " image source = " << image_name << std::endl << std::endl; // 1 - Read neural net // Without next 5 strings net didn't load. How load the net correctly? #ifdef WIN32 auto extension_ptr = InferenceEngine::make_so_pointer<::InferenceEngine::IExtension>(L"cpu_extension_avx2.dll"); #else auto extension_ptr = make_so_pointer<::InferenceEngine::IExtension>("libcpu_extension.so"); #endif InferenceEngine::Core core; InferenceEngine::CNNNetReader network_reader; network_reader.ReadNetwork(model_xml); network_reader.ReadWeights(model_bin); // 2 - Get net from reader class auto network = network_reader.getNetwork(); // 3 - Get i/o info InferenceEngine::InputsDataMap input_info = network.getInputsInfo(); InferenceEngine::OutputsDataMap output_info = network.getOutputsInfo(); if (input_info.size() != 1) { throw std::runtime_error("item.size() != 1"); } if (output_info.size() != 1) { throw std::runtime_error("item.size() != 1"); } std::cout << " input_info.size() = " << input_info.size() << " output_info.size() = " << output_info.size() << std::endl << std::endl; std::cout << "#input/output names: " << std::endl; std::string input_name = input_info .begin()->first; std::string output_name = output_info.begin()->first; std::cout << " input_info.begin() = " << input_name << " output_info.begin() = " << output_name << std::endl << std::endl; // 5 - Load net core.AddExtension(extension_ptr,"CPU"); auto executable_network = core.LoadNetwork(network, "CPU"); // 6 - Create an inference request auto infer_request = executable_network.CreateInferRequest(); // Print input parameters std::cout << "#Input info: " << std::endl; io_info::i_print_info(input_info.at(input_name)); // Print output parameters InferenceEngine::DataPtr o_info = output_info.at(output_name); std::cout << "#Output info: " << std::endl; std::cout << " io_info->getPrecision() = " << o_info->getPrecision () << std::endl; std::cout << " io_info->getLayout () = " << o_info->getLayout () << std::endl; std::cout << " io_info->getName () = " << o_info->getName () << std::endl; std::cout << " io_info->dims = " << o_info->getTensorDesc().getDims() << std::endl; std::cout << std::endl; auto input = infer_request.GetBlob(input_name); // Normalizing of image to [-1/2 .. 1/2) frame = frame / 256.f - 0.5f; OV_helper::matU8ToBlob<float>(frame, input); infer_request.SetBlob(input_name, input); // 8 - Infer request infer_request.Infer(); // 9 - Parse an answer auto output = infer_request.GetBlob(output_name); auto img = OV_helper::blobFP32_to_img1ch(output); cv::imwrite("output_image.bmp", img); } catch (std::exception &e) { std::cout << "Exception raised: " << e.what() << std::endl; } std::cout << "Ok return.\n" << std::endl; return 0; }
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear Corvid, Zabeth,
I don't know the answer by spot-checking your code but I can tell you how to debug this problem. You can dump intermediate layers within your OpenVino app before and after inference - to figure out where the "noisy" or problematic layer is introduced.
You can do this via network.AddOutput("network_name"). Please see the following Intel Developer Zone post which I answered, to get more details.
https://software.intel.com/en-us/forums/computer-vision/topic/816896
Hope it helps,
Thanks,
Shubha
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page