feat: 切换后端至PaddleOCR-NCNN,切换工程为CMake

1.项目后端整体迁移至PaddleOCR-NCNN算法,已通过基本的兼容性测试
2.工程改为使用CMake组织,后续为了更好地兼容第三方库,不再提供QMake工程
3.重整权利声明文件,重整代码工程,确保最小化侵权风险

Log: 切换后端至PaddleOCR-NCNN,切换工程为CMake
Change-Id: I4d5d2c5d37505a4a24b389b1a4c5d12f17bfa38c
This commit is contained in:
wangzhengyang
2022-05-10 09:54:44 +08:00
parent ecdd171c6f
commit 718c41634f
10018 changed files with 3593797 additions and 186748 deletions

View File

View File

@ -0,0 +1,133 @@
#!/usr/bin/env python3
"""
This script builds OpenCV into an xcframework compatible with the platforms
of your choice. Just run it and grab a snack; you'll be waiting a while.
"""
import sys, os, argparse, pathlib, traceback, contextlib, shutil
from cv_build_utils import execute, print_error, print_header, get_xcode_version, get_cmake_version
if __name__ == "__main__":
# Check for dependencies
assert sys.version_info >= (3, 6), "Python 3.6 or later is required! Current version is {}".format(sys.version_info)
# Need CMake 3.18.5/3.19 or later for a Silicon-related fix to building for the iOS Simulator.
# See https://gitlab.kitware.com/cmake/cmake/-/issues/21425 for context.
assert get_cmake_version() >= (3, 18, 5), "CMake 3.18.5 or later is required. Current version is {}".format(get_cmake_version())
# Need Xcode 12.2 for Apple Silicon support
assert get_xcode_version() >= (12, 2), \
"Xcode 12.2 command line tools or later are required! Current version is {}. ".format(get_xcode_version()) + \
"Run xcode-select to switch if you have multiple Xcode installs."
# Parse arguments
description = """
This script builds OpenCV into an xcframework supporting the Apple platforms of your choice.
"""
epilog = """
Any arguments that are not recognized by this script are passed through to the ios/osx build_framework.py scripts.
"""
parser = argparse.ArgumentParser(description=description, epilog=epilog)
parser.add_argument('-o', '--out', metavar='OUTDIR', help='<Required> The directory where the xcframework will be created', required=True)
parser.add_argument('--framework_name', default='opencv2', help='Name of OpenCV xcframework (default: opencv2, will change to OpenCV in future version)')
parser.add_argument('--iphoneos_archs', default=None, help='select iPhoneOS target ARCHS. Default is "armv7,arm64"')
parser.add_argument('--iphonesimulator_archs', default=None, help='select iPhoneSimulator target ARCHS. Default is "x86_64,arm64"')
parser.add_argument('--macos_archs', default=None, help='Select MacOS ARCHS. Default is "x86_64,arm64"')
parser.add_argument('--catalyst_archs', default=None, help='Select Catalyst ARCHS. Default is "x86_64,arm64"')
parser.add_argument('--build_only_specified_archs', default=False, action='store_true', help='if enabled, only directly specified archs are built and defaults are ignored')
args, unknown_args = parser.parse_known_args()
if unknown_args:
print("The following args are not recognized by this script and will be passed through to the ios/osx build_framework.py scripts: {}".format(unknown_args))
# Parse architectures from args
iphoneos_archs = args.iphoneos_archs
if not iphoneos_archs and not args.build_only_specified_archs:
# Supply defaults
iphoneos_archs = "armv7,arm64"
print('Using iPhoneOS ARCHS={}'.format(iphoneos_archs))
iphonesimulator_archs = args.iphonesimulator_archs
if not iphonesimulator_archs and not args.build_only_specified_archs:
# Supply defaults
iphonesimulator_archs = "x86_64,arm64"
print('Using iPhoneSimulator ARCHS={}'.format(iphonesimulator_archs))
macos_archs = args.macos_archs
if not macos_archs and not args.build_only_specified_archs:
# Supply defaults
macos_archs = "x86_64,arm64"
print('Using MacOS ARCHS={}'.format(macos_archs))
catalyst_archs = args.macos_archs
if not catalyst_archs and not args.build_only_specified_archs:
# Supply defaults
catalyst_archs = "x86_64,arm64"
print('Using Catalyst ARCHS={}'.format(catalyst_archs))
# Build phase
try:
# Phase 1: build .frameworks for each platform
osx_script_path = os.path.abspath(os.path.abspath(os.path.dirname(__file__))+'/../osx/build_framework.py')
ios_script_path = os.path.abspath(os.path.abspath(os.path.dirname(__file__))+'/../ios/build_framework.py')
build_folders = []
def get_or_create_build_folder(base_dir, platform):
build_folder = "{}/{}".format(base_dir, platform).replace(" ", "\\ ") # Escape spaces in output path
pathlib.Path(build_folder).mkdir(parents=True, exist_ok=True)
return build_folder
if iphoneos_archs:
build_folder = get_or_create_build_folder(args.out, "iphoneos")
build_folders.append(build_folder)
command = ["python3", ios_script_path, build_folder, "--iphoneos_archs", iphoneos_archs, "--framework_name", args.framework_name, "--build_only_specified_archs"] + unknown_args
print_header("Building iPhoneOS frameworks")
print(command)
execute(command, cwd=os.getcwd())
if iphonesimulator_archs:
build_folder = get_or_create_build_folder(args.out, "iphonesimulator")
build_folders.append(build_folder)
command = ["python3", ios_script_path, build_folder, "--iphonesimulator_archs", iphonesimulator_archs, "--framework_name", args.framework_name, "--build_only_specified_archs"] + unknown_args
print_header("Building iPhoneSimulator frameworks")
execute(command, cwd=os.getcwd())
if macos_archs:
build_folder = get_or_create_build_folder(args.out, "macos")
build_folders.append(build_folder)
command = ["python3", osx_script_path, build_folder, "--macos_archs", macos_archs, "--framework_name", args.framework_name, "--build_only_specified_archs"] + unknown_args
print_header("Building MacOS frameworks")
execute(command, cwd=os.getcwd())
if catalyst_archs:
build_folder = get_or_create_build_folder(args.out, "catalyst")
build_folders.append(build_folder)
command = ["python3", osx_script_path, build_folder, "--catalyst_archs", catalyst_archs, "--framework_name", args.framework_name, "--build_only_specified_archs"] + unknown_args
print_header("Building Catalyst frameworks")
execute(command, cwd=os.getcwd())
# Phase 2: put all the built .frameworks together into a .xcframework
xcframework_path = "{}/{}.xcframework".format(args.out, args.framework_name)
print_header("Building {}".format(xcframework_path))
# Remove the xcframework if it exists, otherwise the existing
# file will cause the xcodebuild command to fail.
with contextlib.suppress(FileNotFoundError):
shutil.rmtree(xcframework_path)
print("Removed existing xcframework at {}".format(xcframework_path))
xcframework_build_command = [
"xcodebuild",
"-create-xcframework",
"-output",
xcframework_path,
]
for folder in build_folders:
xcframework_build_command += ["-framework", "{}/{}.framework".format(folder, args.framework_name)]
execute(xcframework_build_command, cwd=os.getcwd())
print("")
print_header("Finished building {}".format(xcframework_path))
except Exception as e:
print_error(e)
traceback.print_exc(file=sys.stderr)
sys.exit(1)

View File

@ -0,0 +1,65 @@
#!/usr/bin/env python
"""
Common utilities. These should be compatible with Python 2 and 3.
"""
from __future__ import print_function
import sys, re
from subprocess import check_call, check_output, CalledProcessError
def execute(cmd, cwd = None):
print("Executing: %s in %s" % (cmd, cwd), file=sys.stderr)
print('Executing: ' + ' '.join(cmd))
retcode = check_call(cmd, cwd = cwd)
if retcode != 0:
raise Exception("Child returned:", retcode)
def print_header(text):
print("="*60)
print(text)
print("="*60)
def print_error(text):
print("="*60, file=sys.stderr)
print("ERROR: %s" % text, file=sys.stderr)
print("="*60, file=sys.stderr)
def get_xcode_major():
ret = check_output(["xcodebuild", "-version"]).decode('utf-8')
m = re.match(r'Xcode\s+(\d+)\..*', ret, flags=re.IGNORECASE)
if m:
return int(m.group(1))
else:
raise Exception("Failed to parse Xcode version")
def get_xcode_version():
"""
Returns the major and minor version of the current Xcode
command line tools as a tuple of (major, minor)
"""
ret = check_output(["xcodebuild", "-version"]).decode('utf-8')
m = re.match(r'Xcode\s+(\d+)\.(\d+)', ret, flags=re.IGNORECASE)
if m:
return (int(m.group(1)), int(m.group(2)))
else:
raise Exception("Failed to parse Xcode version")
def get_xcode_setting(var, projectdir):
ret = check_output(["xcodebuild", "-showBuildSettings"], cwd = projectdir).decode('utf-8')
m = re.search("\s" + var + " = (.*)", ret)
if m:
return m.group(1)
else:
raise Exception("Failed to parse Xcode settings")
def get_cmake_version():
"""
Returns the major and minor version of the current CMake
command line tools as a tuple of (major, minor, revision)
"""
ret = check_output(["cmake", "--version"]).decode('utf-8')
m = re.match(r'cmake\sversion\s+(\d+)\.(\d+).(\d+)', ret, flags=re.IGNORECASE)
if m:
return (int(m.group(1)), int(m.group(2)), int(m.group(3)))
else:
raise Exception("Failed to parse CMake version")

View File

@ -0,0 +1,56 @@
# Building for Apple Platforms
build_xcframework.py creates an xcframework supporting a variety of Apple platforms.
You'll need the following to run these steps:
- MacOS 10.15 or later
- Python 3.6 or later
- CMake 3.18.5/3.19.0 or later (make sure the `cmake` command is available on your PATH)
- Xcode 12.2 or later (and its command line tools)
You can then run build_xcframework.py, as below:
```
cd ~/<my_working_directory>
python opencv/platforms/apple/build_xcframework.py --out ./build_xcframework
```
Grab a coffee, because you'll be here for a while. By default this builds OpenCV for 8 architectures across 4 platforms:
- iOS (`--iphoneos_archs`): arm64, armv7
- iOS Simulator (`--iphonesimulator_archs`): x86_64, arm64
- macOS (`--macos_archs`): x86_64, arm64
- Mac Catalyst (`--catalyst_archs`): x86_64, arm64
If everything's fine, you will eventually get `opencv2.xcframework` in the output directory.
The script has some configuration options to exclude platforms and architectures you don't want to build for. Use the `--help` flag for more information.
## How it Works
This script generates a fat `.framework` for each platform you specify, and stitches them together into a `.xcframework`. This file can be used to support the same architecture on different platforms, which fat `.framework`s don't allow. To build the intermediate `.framework`s, `build_xcframework.py` leverages the `build_framework.py` scripts in the ios and osx platform folders.
### Passthrough Arguments
Any arguments that aren't recognized by `build_xcframework.py` will be passed to the platform-specific `build_framework.py` scripts. The `--without` flag mentioned in the examples is an example of this in action. For more info, see the `--help` info for those scripts.
## Examples
You may override the defaults by specifying a value for any of the `*_archs` flags. For example, if you want to build for arm64 on every platform, you can do this:
```
python build_xcframework.py --out somedir --iphoneos_archs arm64 --iphonesimulator_archs arm64 --macos_archs arm64 --catalyst_archs arm64
```
If you want to build only for certain platforms, you can supply the `--build_only_specified_archs` flag, which makes the script build only the archs you directly ask for. For example, to build only for Catalyst, you can do this:
```
python build_xcframework.py --out somedir --catalyst_archs x86_64,arm64 --build_only_specified_archs
```
You can also build without OpenCV functionality you don't need. You can do this by using the `--without` flag, which you use once per item you want to go without. For example, if you wanted to compile without `video` or `objc`, you'd can do this:
```
python build_xcframework.py --out somedir --without video --without objc
```
(if you have issues with this, try using `=`, e.g. `--without=video --without=objc`, and file an issue on GitHub.)