Skip to main content

🚰🔌 Power Meter and Water Meter OCR

🚰🔌 ระบบสำหรับอ่านตัวเลขบนมิเตอร์ไฟฟ้าและมิเตอร์น้ำ

Version Status

Water Meter OCR is an iApp's AI service that automatically reads and digitizes water meter and power meter readings. The service can detect and extract numbers from both round and rectangular meter faces.

Getting Started

  1. Prerequisites

    • An API key from iApp Technology
    • Clear images of water/power meters
    • Internet connection
  2. Quick Start

    • Fast meter reading recognition
    • Support for multiple meter types
    • Simple REST API interface
  3. Key Features

    • Automated meter reading detection
    • High accuracy digit recognition
    • Fast response time
    • Easy integration
  4. Security & Compliance

    • GDPR and PDPA compliant
    • No data retention after processing
How to get API Key?

Please visit API Portal to view your existing API key or request a new one.

Example

Power and Water Meter in Real Life Application

1. Water Meter With Round Face

Example 1 Power and Water Meter Example 1

Example 2 Power and Water Meter Example 2

2. Water Meter With Rectangle Face

Power and Water Meter Example 3

Request

curl --location --request POST 'https://api.iapp.co.th/meter-number-ocr/file' \
--header 'apikey: ----Your API Key----' \
--form 'file=@"/Users/id_1016_value_367_003.jpg"'

Response

{
"infer_time": 0.16,
"label": "024963",
"message": "success",
"status": 200
}

Features & Capabilities

Core Features

  • Automatic detection of meter faces (round and rectangular)
  • High-accuracy digit recognition
  • Fast processing time
  • Support for multiple image formats

Supported Fields

  • Meter reading numbers
  • Meter face type detection

API Reference

Endpoint

POST https://api.iapp.co.th/meter-number-ocr/file

Headers

NameTypeDescription
apikeystringYour API key

Request Body

NameTypeDescription
fileimageClear meter image

Code Example

Python

import requests

url = "https://api.iapp.co.th/meter-number-ocr/file"

payload = {}
files=[
('file',('{YOUR UPLOADED FILE NAME}',open('{YOUR UPLOADED FILE PATH}','rb'),'image/png'))
]
headers = {
'apikey': '{YOUR_API_KEY}'
}

response = requests.request("POST", url, headers=headers, data=payload, files=files)

print(response.text)

JavaScript

const axios = require('axios');
const FormData = require('form-data');
const fs = require('fs');
let data = new FormData();
data.append('file', fs.createReadStream('{YOUR UPLOADED FILE PATH}'));

let config = {
method: 'post',
maxBodyLength: Infinity,
url: 'https://api.iapp.co.th/meter-number-ocr/file',
headers: {
'apikey': '{YOUR_API_KEY}',
...data.getHeaders()
},
data : data
};

axios.request(config)
.then((response) => {
console.log(JSON.stringify(response.data));
})
.catch((error) => {
console.log(error);
});

PHP

<?php

$curl = curl_init();

curl_setopt_array($curl, array(
CURLOPT_URL => 'https://api.iapp.co.th/meter-number-ocr/file',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => array('file'=> new CURLFILE('{YOUR UPLOADED FILE PATH}')),
CURLOPT_HTTPHEADER => array(
'apikey: {YOUR_API_KEY}'
),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;

Swift

let parameters = [
[
"key": "file",
"src": "{YOUR UPLOADED FILE PATH}",
"type": "file"
]] as [[String: Any]]

let boundary = "Boundary-\(UUID().uuidString)"
var body = Data()
var error: Error? = nil
for param in parameters {
if param["disabled"] != nil { continue }
let paramName = param["key"]!
body += Data("--\(boundary)\r\n".utf8)
body += Data("Content-Disposition:form-data; name=\"\(paramName)\"".utf8)
if param["contentType"] != nil {
body += Data("\r\nContent-Type: \(param["contentType"] as! String)".utf8)
}
let paramType = param["type"] as! String
if paramType == "text" {
let paramValue = param["value"] as! String
body += Data("\r\n\r\n\(paramValue)\r\n".utf8)
} else {
let paramSrc = param["src"] as! String
let fileURL = URL(fileURLWithPath: paramSrc)
if let fileContent = try? Data(contentsOf: fileURL) {
body += Data("; filename=\"\(paramSrc)\"\r\n".utf8)
body += Data("Content-Type: \"content-type header\"\r\n".utf8)
body += Data("\r\n".utf8)
body += fileContent
body += Data("\r\n".utf8)
}
}
}
body += Data("--\(boundary)--\r\n".utf8);
let postData = body


var request = URLRequest(url: URL(string: "https://api.iapp.co.th/meter-number-ocr/file")!,timeoutInterval: Double.infinity)
request.addValue("{YOUR_API_KEY}", forHTTPHeaderField: "apikey")
request.addValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")

request.httpMethod = "POST"
request.httpBody = postData

let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data else {
print(String(describing: error))
return
}
print(String(data: data, encoding: .utf8)!)
}

task.resume()

Kotlin

val client = OkHttpClient()
val mediaType = "text/plain".toMediaType()
val body = MultipartBody.Builder().setType(MultipartBody.FORM)
.addFormDataPart("file","{YOUR UPLOADED FILE NAME}",
File("{YOUR UPLOADED FILE PATH}").asRequestBody("application/octet-stream".toMediaType()))
.build()
val request = Request.Builder()
.url("https://api.iapp.co.th/meter-number-ocr/file")
.post(body)
.addHeader("apikey", "{YOUR_API_KEY}")
.build()
val response = client.newCall(request).execute()

Java

OkHttpClient client = new OkHttpClient().newBuilder()
.build();
MediaType mediaType = MediaType.parse("text/plain");
RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM)
.addFormDataPart("file","{YOUR UPLOADED FILE NAME}",
RequestBody.create(MediaType.parse("application/octet-stream"),
new File("{YOUR UPLOADED FILE PATH}")))
.build();
Request request = new Request.Builder()
.url("https://api.iapp.co.th/meter-number-ocr/file")
.method("POST", body)
.addHeader("apikey", "{YOUR_API_KEY}")
.build();
Response response = client.newCall(request).execute();

Dart

var headers = {
'apikey': '{YOUR_API_KEY}'
};
var request = http.MultipartRequest('POST', Uri.parse('https://api.iapp.co.th/meter-number-ocr/file'));
request.files.add(await http.MultipartFile.fromPath('file', '{YOUR UPLOADED FILE PATH}'));
request.headers.addAll(headers);

http.StreamedResponse response = await request.send();

if (response.statusCode == 200) {
print(await response.stream.bytesToString());
}
else {
print(response.reasonPhrase);
}

Accuracy and Performance

Evaluation done based on Water-Meter image data of both rectangle and round faces (107 images)

Model Evaluation

ModelDescriptionAccuracy (%)
Water Meter Detection ModelDetects the water meter from the input image96.22
OCR ModelRecognizes the Digits76.47
Overall AccuracyOverall accuracy of the system73.58

Character Evaluation

NumbersTotal CountCorrect CountAccuracy (%)
019718895.43
1858094.12
2585391.38
3696391.3
4656295.38
5575087.72
6514384.31
7524892.31
8484083.33
9595084.75

Overall Accuracy based on True detection of numbers = 90 %

History/Change Logs

Version 1.0 - 2021-10-05

Added

  • Introducing iApp's water meter OCR
  • Supports all kind of water meter faces

Version 1.1 - 2021-12-02

Fixed

  • Detection of 2 digits on same x coordinate
  • Increased Accuracy from 62.26 to 73.58

Pricing

AI API Service NameIC Per RequestOn-Premise
Power and Meter OCR1 IC/RequestContact