🚰🔌 Power Meter and Water Meter OCR
🚰🔌 ระบบสำหรับอ่านตัวเลขบนมิเตอร์ไฟฟ้าและมิเตอร์น้ำ
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
-
Prerequisites
- An API key from iApp Technology
- Clear images of water/power meters
- Internet connection
-
Quick Start
- Fast meter reading recognition
- Support for multiple meter types
- Simple REST API interface
-
Key Features
- Automated meter reading detection
- High accuracy digit recognition
- Fast response time
- Easy integration
-
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
Example 2
2. Water Meter With Rectangle Face
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
Name | Type | Description |
---|---|---|
apikey | string | Your API key |
Request Body
Name | Type | Description |
---|---|---|
file | image | Clear 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
Model | Description | Accuracy (%) |
---|---|---|
Water Meter Detection Model | Detects the water meter from the input image | 96.22 |
OCR Model | Recognizes the Digits | 76.47 |
Overall Accuracy | Overall accuracy of the system | 73.58 |
Character Evaluation
Numbers | Total Count | Correct Count | Accuracy (%) |
---|---|---|---|
0 | 197 | 188 | 95.43 |
1 | 85 | 80 | 94.12 |
2 | 58 | 53 | 91.38 |
3 | 69 | 63 | 91.3 |
4 | 65 | 62 | 95.38 |
5 | 57 | 50 | 87.72 |
6 | 51 | 43 | 84.31 |
7 | 52 | 48 | 92.31 |
8 | 48 | 40 | 83.33 |
9 | 59 | 50 | 84.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 Name | IC Per Request | On-Premise |
---|---|---|
Power and Meter OCR | 1 IC/Request | Contact |