Skip to content

Commit 884e20b

Browse files
committed
Add support to PaddleOCR V6 models, add image orentation model
1 parent 9160681 commit 884e20b

34 files changed

Lines changed: 1403 additions & 74 deletions

build/00-common.linq

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ static ProjectVersion[] Projects = new[]
2323
{
2424
new ProjectVersion("Sdcb.OpenVINO", "0.7.1"),
2525
new ProjectVersion("Sdcb.OpenVINO.Extensions.OpenCvSharp4", "0.7.0"),
26-
new ProjectVersion("Sdcb.OpenVINO.PaddleOCR", "0.7.0"),
27-
new ProjectVersion("Sdcb.OpenVINO.PaddleOCR.Models.Online", "0.7.1"),
26+
new ProjectVersion("Sdcb.OpenVINO.PaddleOCR", "0.8.0"),
27+
new ProjectVersion("Sdcb.OpenVINO.PaddleOCR.Models.Online", "0.8.0"),
2828
};
2929

3030
static async Task DownloadFile(Uri uri, string localFile, CancellationToken cancellationToken = default)

projects/PaddleOCR/Sdcb.OpenVINO.PaddleOCR.Models.Online/Details/Utils.cs

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,15 @@ public static async Task DownloadFiles(Uri[] uris, string localFile, Cancellatio
5252
throw new Exception($"Failed to download {localFile} from all uris: {string.Join(", ", uris.Select(x => x.ToString()))}");
5353
}
5454

55-
public static async Task DownloadAndExtractAsync(string name, Uri uri, string rootDir, CancellationToken cancellationToken)
55+
public static async Task DownloadAndExtractAsync(string name, Uri uri, string rootDir, CancellationToken cancellationToken, params string[] expectedFileNames)
5656
{
5757
Directory.CreateDirectory(rootDir);
58-
string paramsFile = Path.Combine(rootDir, "inference.pdiparams");
58+
if (expectedFileNames == null || expectedFileNames.Length == 0)
59+
{
60+
expectedFileNames = new[] { "inference.pdiparams", "inference.pdmodel" };
61+
}
5962

60-
if (!File.Exists(paramsFile))
63+
if (!CheckLocalModel(rootDir, expectedFileNames, throwOnError: false))
6164
{
6265
string localTarFile = Path.Combine(rootDir, uri.Segments.Last());
6366
if (!File.Exists(localTarFile) || new FileInfo(localTarFile).Length == 0)
@@ -94,7 +97,7 @@ public static async Task DownloadAndExtractAsync(string name, Uri uri, string ro
9497
archive.WriteToDirectory(rootDir);
9598
}
9699

97-
CheckLocalOCRModel(rootDir);
100+
CheckLocalModel(rootDir, expectedFileNames, throwOnError: true);
98101
}
99102

100103
File.Delete(localTarFile);
@@ -193,26 +196,29 @@ private static string GetDestinationPath(string rootDir, string relativePath)
193196

194197
public static void CheckLocalOCRModel(string rootDir)
195198
{
196-
string[] filesToCheck = new[]
197-
{
198-
Path.Combine(rootDir, "inference.pdiparams"),
199-
Path.Combine(rootDir, "inference.pdmodel"),
200-
};
199+
CheckLocalModel(rootDir, new[] { "inference.pdiparams", "inference.pdmodel" }, throwOnError: true);
200+
}
201201

202-
foreach (string path in filesToCheck)
202+
private static bool CheckLocalModel(string rootDir, string[] expectedFileNames, bool throwOnError)
203+
{
204+
foreach (string fileName in expectedFileNames)
203205
{
204-
string fileName = Path.GetFileName(path);
206+
string path = Path.Combine(rootDir, fileName);
205207

206208
if (!File.Exists(path))
207209
{
210+
if (!throwOnError) return false;
208211
throw new Exception($"{fileName} not found in {rootDir}, model error?");
209212
}
210213

211214
if (new FileInfo(path).Length == 0)
212215
{
216+
if (!throwOnError) return false;
213217
throw new Exception($"{fileName} invalid(length = 0), model error?");
214218
}
215219
}
220+
221+
return true;
216222
}
217223

218224
public readonly static Type RootType = typeof(Settings);
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
using Sdcb.OpenVINO.PaddleOCR.Models;
2+
using System.Threading;
3+
using System.Threading.Tasks;
4+
5+
namespace Sdcb.OpenVINO.PaddleOCR.Models.Online;
6+
7+
/// <summary>
8+
/// Represents an online detection model.
9+
/// </summary>
10+
public interface IOnlineDetectionModel
11+
{
12+
/// <summary>
13+
/// Downloads the model asynchronously.
14+
/// </summary>
15+
Task<DetectionModel> DownloadAsync(CancellationToken cancellationToken = default);
16+
}
17+
18+
/// <summary>
19+
/// Represents an online text line orientation classification model.
20+
/// </summary>
21+
public interface IOnlineClassificationModel
22+
{
23+
/// <summary>
24+
/// Downloads the model asynchronously.
25+
/// </summary>
26+
Task<ClassificationModel> DownloadAsync(CancellationToken cancellationToken = default);
27+
}
28+
29+
/// <summary>
30+
/// Represents an online recognition model.
31+
/// </summary>
32+
public interface IOnlineRecognizationModel
33+
{
34+
/// <summary>
35+
/// Downloads the model asynchronously.
36+
/// </summary>
37+
Task<RecognizationModel> DownloadAsync(CancellationToken cancellationToken = default);
38+
}
39+
40+
/// <summary>
41+
/// Represents an online document orientation classification model.
42+
/// </summary>
43+
public interface IOnlineDocumentOrientationClassificationModel
44+
{
45+
/// <summary>
46+
/// Downloads the model asynchronously.
47+
/// </summary>
48+
Task<DocumentOrientationClassificationModel> DownloadAsync(CancellationToken cancellationToken = default);
49+
}

projects/PaddleOCR/Sdcb.OpenVINO.PaddleOCR.Models.Online/LocalDictOnlineRecognizationModel.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ namespace Sdcb.OpenVINO.PaddleOCR.Models.Online;
1313
/// <remarks>
1414
/// Used for downloading and extracting a model from a url, and creating a new StreamDictFileRecognizationModel with the downloaded contents.
1515
/// </remarks>
16-
public record LocalDictOnlineRecognizationModel(string Name, string DictName, Uri Uri, ModelVersion Version)
16+
public record LocalDictOnlineRecognizationModel(string Name, string DictName, Uri Uri, ModelVersion Version) : IOnlineRecognizationModel
1717
{
1818
/// <summary>
1919
/// Gets or sets the root directory for the downloaded models.

projects/PaddleOCR/Sdcb.OpenVINO.PaddleOCR.Models.Online/OnlineClassificationModel.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ namespace Sdcb.OpenVINO.PaddleOCR.Models.Online;
1010
/// <summary>
1111
/// Represents an online classification model that can be downloaded and used for text angle classification.
1212
/// </summary>
13-
public record OnlineClassificationModel(string Name, Uri Uri, ModelVersion Version)
13+
public record OnlineClassificationModel(string Name, Uri Uri, ModelVersion Version) : IOnlineClassificationModel
1414
{
1515
/// <summary>
1616
/// Gets the root directory of the model.
@@ -28,6 +28,11 @@ public async Task<FileClassificationModel> DownloadAsync(CancellationToken cance
2828
return new FileClassificationModel(RootDirectory, Version);
2929
}
3030

31+
async Task<ClassificationModel> IOnlineClassificationModel.DownloadAsync(CancellationToken cancellationToken)
32+
{
33+
return await DownloadAsync(cancellationToken);
34+
}
35+
3136
/// <summary>
3237
/// Gets an online classification model for slim quantized text angle classification (Size: 2.1M).
3338
/// </summary>

projects/PaddleOCR/Sdcb.OpenVINO.PaddleOCR.Models.Online/OnlineDetectionModel.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ namespace Sdcb.OpenVINO.PaddleOCR.Models.Online;
1010
/// <summary>
1111
/// Represents a model for online object detection.
1212
/// </summary>
13-
public record OnlineDetectionModel(string Name, Uri Uri, ModelVersion Version)
13+
public record OnlineDetectionModel(string Name, Uri Uri, ModelVersion Version) : IOnlineDetectionModel
1414
{
1515
/// <summary>
1616
/// Gets the root directory of the model.
@@ -29,6 +29,11 @@ public async Task<FileDetectionModel> DownloadAsync(CancellationToken cancellati
2929
return new FileDetectionModel(RootDirectory, Version);
3030
}
3131

32+
async Task<DetectionModel> IOnlineDetectionModel.DownloadAsync(CancellationToken cancellationToken)
33+
{
34+
return await DownloadAsync(cancellationToken);
35+
}
36+
3237
/// <summary>
3338
/// [New] v4 model, supporting Chinese, English, multilingual text detection
3439
/// (Size: 4.66M)
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
using Sdcb.OpenVINO.PaddleOCR.Models;
2+
using Sdcb.OpenVINO.PaddleOCR.Models.Details;
3+
using Sdcb.OpenVINO.PaddleOCR.Models.Online.Details;
4+
using System;
5+
using System.IO;
6+
using System.Threading;
7+
using System.Threading.Tasks;
8+
9+
namespace Sdcb.OpenVINO.PaddleOCR.Models.Online;
10+
11+
/// <summary>
12+
/// Represents an online ONNX document orientation classification model.
13+
/// </summary>
14+
public record OnlineDocumentOrientationClassificationModel(string Name, Uri Uri) : IOnlineDocumentOrientationClassificationModel
15+
{
16+
/// <summary>
17+
/// Gets the root directory of the model.
18+
/// </summary>
19+
public string RootDirectory => Path.Combine(Settings.GlobalModelDirectory, Name);
20+
21+
/// <summary>
22+
/// Downloads and extracts the model asynchronously.
23+
/// </summary>
24+
public async Task<FileDocumentOrientationClassificationModel> DownloadAsync(CancellationToken cancellationToken = default)
25+
{
26+
await Utils.DownloadAndExtractAsync(Name, Uri, RootDirectory, cancellationToken, "inference.onnx", "inference.yml");
27+
return new FileDocumentOrientationClassificationModel(RootDirectory);
28+
}
29+
30+
async Task<DocumentOrientationClassificationModel> IOnlineDocumentOrientationClassificationModel.DownloadAsync(CancellationToken cancellationToken)
31+
{
32+
return await DownloadAsync(cancellationToken);
33+
}
34+
35+
/// <summary>
36+
/// PP-LCNet x1.0 document orientation model.
37+
/// </summary>
38+
public static OnlineDocumentOrientationClassificationModel PPDocOrientationX10 => new("PP-LCNet_x1_0_doc_ori_onnx_infer", new Uri("https://paddle-model-ecology.bj.bcebos.com/paddlex/official_inference_model/paddle3.0.0/PP-LCNet_x1_0_doc_ori_onnx_infer.tar"));
39+
}

projects/PaddleOCR/Sdcb.OpenVINO.PaddleOCR.Models.Online/OnlineFullModels.cs

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,11 @@ namespace Sdcb.OpenVINO.PaddleOCR.Models.Online;
1010
/// <remarks>
1111
/// Contains static instances for commonly used models and a method for downloading a full OCR model.
1212
/// </remarks>
13-
public record class OnlineFullModels(OnlineDetectionModel DetModel, OnlineClassificationModel? ClsModel, LocalDictOnlineRecognizationModel RecModel)
13+
public record class OnlineFullModels(
14+
IOnlineDetectionModel DetModel,
15+
IOnlineClassificationModel? ClsModel,
16+
IOnlineRecognizationModel RecModel,
17+
IOnlineDocumentOrientationClassificationModel? DocOrientationModel = null)
1418
{
1519
/// <summary>
1620
/// Downloads a full OCR model asynchronously.
@@ -19,12 +23,40 @@ public record class OnlineFullModels(OnlineDetectionModel DetModel, OnlineClassi
1923
/// <returns><see cref="FullOcrModel"/> instance.</returns>
2024
public async Task<FullOcrModel> DownloadAsync(CancellationToken cancellationToken = default)
2125
{
22-
FileDetectionModel localDetModel = await DetModel.DownloadAsync(cancellationToken);
23-
FileClassificationModel? localClsModel = ClsModel != null ? await ClsModel.DownloadAsync(cancellationToken) : null;
26+
DetectionModel localDetModel = await DetModel.DownloadAsync(cancellationToken);
27+
ClassificationModel? localClsModel = ClsModel != null ? await ClsModel.DownloadAsync(cancellationToken) : null;
2428
RecognizationModel localRecModel = await RecModel.DownloadAsync(cancellationToken);
25-
return new FullOcrModel(localDetModel, localClsModel, localRecModel);
29+
DocumentOrientationClassificationModel? localDocOrientationModel = DocOrientationModel != null ? await DocOrientationModel.DownloadAsync(cancellationToken) : null;
30+
return new FullOcrModel(localDetModel, localClsModel, localRecModel, localDocOrientationModel);
2631
}
2732

33+
/// <summary>
34+
/// The Chinese PP-OCRv6 medium ONNX version.
35+
/// </summary>
36+
public readonly static OnlineFullModels ChineseV6Medium = new(
37+
OnlineOnnxDetectionModel.ChineseV6Medium,
38+
OnlineOnnxClassificationModel.TextLineOrientationX10,
39+
OnlineOnnxRecognizationModel.ChineseV6Medium,
40+
OnlineDocumentOrientationClassificationModel.PPDocOrientationX10);
41+
42+
/// <summary>
43+
/// The Chinese PP-OCRv6 small ONNX version.
44+
/// </summary>
45+
public readonly static OnlineFullModels ChineseV6Small = new(
46+
OnlineOnnxDetectionModel.ChineseV6Small,
47+
OnlineOnnxClassificationModel.TextLineOrientationX025,
48+
OnlineOnnxRecognizationModel.ChineseV6Small,
49+
OnlineDocumentOrientationClassificationModel.PPDocOrientationX10);
50+
51+
/// <summary>
52+
/// The Chinese PP-OCRv6 tiny ONNX version.
53+
/// </summary>
54+
public readonly static OnlineFullModels ChineseV6Tiny = new(
55+
OnlineOnnxDetectionModel.ChineseV6Tiny,
56+
OnlineOnnxClassificationModel.TextLineOrientationX025,
57+
OnlineOnnxRecognizationModel.ChineseV6Tiny,
58+
OnlineDocumentOrientationClassificationModel.PPDocOrientationX10);
59+
2860
/// <summary>
2961
/// The Chinese V4 version.
3062
/// </summary>
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
using Sdcb.OpenVINO.PaddleOCR.Models;
2+
using Sdcb.OpenVINO.PaddleOCR.Models.Details;
3+
using Sdcb.OpenVINO.PaddleOCR.Models.Online.Details;
4+
using System;
5+
using System.IO;
6+
using System.Threading;
7+
using System.Threading.Tasks;
8+
9+
namespace Sdcb.OpenVINO.PaddleOCR.Models.Online;
10+
11+
/// <summary>
12+
/// Represents an online ONNX text line orientation classification model.
13+
/// </summary>
14+
public record OnlineOnnxClassificationModel(string Name, Uri Uri, ModelVersion Version, NCHW Shape) : IOnlineClassificationModel
15+
{
16+
/// <summary>
17+
/// Gets the root directory of the model.
18+
/// </summary>
19+
public string RootDirectory => Path.Combine(Settings.GlobalModelDirectory, Name);
20+
21+
/// <summary>
22+
/// Downloads and extracts the model asynchronously.
23+
/// </summary>
24+
public async Task<FileOnnxClassificationModel> DownloadAsync(CancellationToken cancellationToken = default)
25+
{
26+
await Utils.DownloadAndExtractAsync(Name, Uri, RootDirectory, cancellationToken, "inference.onnx", "inference.yml");
27+
return new FileOnnxClassificationModel(RootDirectory, Version, Shape);
28+
}
29+
30+
async Task<ClassificationModel> IOnlineClassificationModel.DownloadAsync(CancellationToken cancellationToken)
31+
{
32+
return await DownloadAsync(cancellationToken);
33+
}
34+
35+
/// <summary>
36+
/// PP-LCNet x0.25 text line orientation model.
37+
/// </summary>
38+
public static OnlineOnnxClassificationModel TextLineOrientationX025 => new("PP-LCNet_x0_25_textline_ori_onnx_infer", new Uri("https://paddle-model-ecology.bj.bcebos.com/paddlex/official_inference_model/paddle3.0.0/PP-LCNet_x0_25_textline_ori_onnx_infer.tar"), ModelVersion.V6, new NCHW(-1, 3, 80, 160));
39+
40+
/// <summary>
41+
/// PP-LCNet x1.0 text line orientation model.
42+
/// </summary>
43+
public static OnlineOnnxClassificationModel TextLineOrientationX10 => new("PP-LCNet_x1_0_textline_ori_onnx_infer", new Uri("https://paddle-model-ecology.bj.bcebos.com/paddlex/official_inference_model/paddle3.0.0/PP-LCNet_x1_0_textline_ori_onnx_infer.tar"), ModelVersion.V6, new NCHW(-1, 3, 80, 160));
44+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
using Sdcb.OpenVINO.PaddleOCR.Models;
2+
using Sdcb.OpenVINO.PaddleOCR.Models.Details;
3+
using Sdcb.OpenVINO.PaddleOCR.Models.Online.Details;
4+
using System;
5+
using System.IO;
6+
using System.Threading;
7+
using System.Threading.Tasks;
8+
9+
namespace Sdcb.OpenVINO.PaddleOCR.Models.Online;
10+
11+
/// <summary>
12+
/// Represents an online ONNX detection model.
13+
/// </summary>
14+
public record OnlineOnnxDetectionModel(string Name, Uri Uri, ModelVersion Version) : IOnlineDetectionModel
15+
{
16+
/// <summary>
17+
/// Gets the root directory of the model.
18+
/// </summary>
19+
public string RootDirectory => Path.Combine(Settings.GlobalModelDirectory, Name);
20+
21+
/// <summary>
22+
/// Downloads and extracts the model files to the root directory asynchronously.
23+
/// </summary>
24+
public async Task<FileOnnxDetectionModel> DownloadAsync(CancellationToken cancellationToken = default)
25+
{
26+
await Utils.DownloadAndExtractAsync(Name, Uri, RootDirectory, cancellationToken, "inference.onnx");
27+
return new FileOnnxDetectionModel(RootDirectory, Version);
28+
}
29+
30+
async Task<DetectionModel> IOnlineDetectionModel.DownloadAsync(CancellationToken cancellationToken)
31+
{
32+
return await DownloadAsync(cancellationToken);
33+
}
34+
35+
/// <summary>
36+
/// PP-OCRv6 medium detection model.
37+
/// </summary>
38+
public static OnlineOnnxDetectionModel ChineseV6Medium => new("PP-OCRv6_medium_det_onnx_infer", new Uri("https://paddle-model-ecology.bj.bcebos.com/paddlex/official_inference_model/paddle3.0.0/PP-OCRv6_medium_det_onnx_infer.tar"), ModelVersion.V6);
39+
40+
/// <summary>
41+
/// PP-OCRv6 small detection model.
42+
/// </summary>
43+
public static OnlineOnnxDetectionModel ChineseV6Small => new("PP-OCRv6_small_det_onnx_infer", new Uri("https://paddle-model-ecology.bj.bcebos.com/paddlex/official_inference_model/paddle3.0.0/PP-OCRv6_small_det_onnx_infer.tar"), ModelVersion.V6);
44+
45+
/// <summary>
46+
/// PP-OCRv6 tiny detection model.
47+
/// </summary>
48+
public static OnlineOnnxDetectionModel ChineseV6Tiny => new("PP-OCRv6_tiny_det_onnx_infer", new Uri("https://paddle-model-ecology.bj.bcebos.com/paddlex/official_inference_model/paddle3.0.0/PP-OCRv6_tiny_det_onnx_infer.tar"), ModelVersion.V6);
49+
}

0 commit comments

Comments
 (0)