Working with this model in C++
Hello Mr @MKgoud
Your model works great at detecting license plates in Python. Long story short: have you ever tried saving your model as an ONNX file?
I wanted to use it in C++ therefore I exported it as an ONNX file model.export(format="onnx", imgsz=(640, 480))
. Unfortunately there is a lot of preprocessing and post-processing that is missing from the onnx file. When using the .pt model I could have just run inference as output = model(img)
. The ONNX file expects a float32 input with dimensions (1,3,640,480). That makes sense. But should the input be normalized to [0,1] range? Or maybe standarized? Should it be BGR or RGB? Or maybe I should have saved onnx with size(480,640)? There are many possibilities. So far I experimented in Python. I was unable to achieve the same detection result with onnx file as I had with the pt file.
I learned that I can export this model as TorchScript so that it can be used in C++ with LibTorch library. I exported it in Python like this:model.export(format="torchscipt", imgsz=(640,640))
Then I used it in C++ (with Qt and LibTorch) like this:
torch::jit::Module lpDetection = torch::jit::load("LP-detection.torchscript");
lpDetection.eval();
QImage image("car1.jpeg");
QImage rgbImage = image.convertToFormat(QImage::Format_RGB888);
rgbImage = rgbImage.scaled(640, 640);
// Get the image dimensions
int width = rgbImage.width();
int height = rgbImage.height();
// Normalize pixel values to [0, 1]
torch::Tensor tensor = torch::from_blob(
const_cast<uchar*>(rgbImage.bits()), // Data pointer
{height, width, 3}, // Tensor dimensions (HWC)
torch::kUInt8 // Data type
).to(torch::kFloat32) / 255.0;
// Permute dimensions from HWC to CHW and add batch dimension
tensor = tensor.permute({2, 0, 1}).unsqueeze(0);
c10::IValue outputVal = lpDetection.forward({tensor});