1.项目后端整体迁移至PaddleOCR-NCNN算法,已通过基本的兼容性测试 2.工程改为使用CMake组织,后续为了更好地兼容第三方库,不再提供QMake工程 3.重整权利声明文件,重整代码工程,确保最小化侵权风险 Log: 切换后端至PaddleOCR-NCNN,切换工程为CMake Change-Id: I4d5d2c5d37505a4a24b389b1a4c5d12f17bfa38c
191 lines
5.4 KiB
Python
191 lines
5.4 KiB
Python
# Tencent is pleased to support the open source community by making ncnn available.
|
|
#
|
|
# Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
|
|
#
|
|
# Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
|
|
# in compliance with the License. You may obtain a copy of the License at
|
|
#
|
|
# https://opensource.org/licenses/BSD-3-Clause
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software distributed
|
|
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
# specific language governing permissions and limitations under the License.
|
|
|
|
import ncnn
|
|
from .model_store import get_model_file
|
|
from ..utils.objects import Detect_Object
|
|
|
|
|
|
class YoloV4_Base:
|
|
def __init__(self, tiny, target_size, num_threads=1, use_gpu=False):
|
|
self.target_size = target_size
|
|
self.num_threads = num_threads
|
|
self.use_gpu = use_gpu
|
|
|
|
self.mean_vals = []
|
|
self.norm_vals = [1 / 255.0, 1 / 255.0, 1 / 255.0]
|
|
|
|
self.net = ncnn.Net()
|
|
self.net.opt.use_vulkan_compute = self.use_gpu
|
|
self.net.opt.num_threads = self.num_threads
|
|
|
|
# original pretrained model from https://github.com/AlexeyAB/darknet
|
|
# the ncnn model https://drive.google.com/drive/folders/1YzILvh0SKQPS_lrb33dmGNq7aVTKPWS0?usp=sharing
|
|
# the ncnn model https://github.com/nihui/ncnn-assets/tree/master/models
|
|
if tiny == True:
|
|
self.net.load_param(get_model_file("yolov4-tiny-opt.param"))
|
|
self.net.load_model(get_model_file("yolov4-tiny-opt.bin"))
|
|
else:
|
|
self.net.load_param(get_model_file("yolov4-opt.param"))
|
|
self.net.load_model(get_model_file("yolov4-opt.bin"))
|
|
|
|
self.class_names = [
|
|
"background",
|
|
"person",
|
|
"bicycle",
|
|
"car",
|
|
"motorbike",
|
|
"aeroplane",
|
|
"bus",
|
|
"train",
|
|
"truck",
|
|
"boat",
|
|
"traffic light",
|
|
"fire hydrant",
|
|
"stop sign",
|
|
"parking meter",
|
|
"bench",
|
|
"bird",
|
|
"cat",
|
|
"dog",
|
|
"horse",
|
|
"sheep",
|
|
"cow",
|
|
"elephant",
|
|
"bear",
|
|
"zebra",
|
|
"giraffe",
|
|
"backpack",
|
|
"umbrella",
|
|
"handbag",
|
|
"tie",
|
|
"suitcase",
|
|
"frisbee",
|
|
"skis",
|
|
"snowboard",
|
|
"sports ball",
|
|
"kite",
|
|
"baseball bat",
|
|
"baseball glove",
|
|
"skateboard",
|
|
"surfboard",
|
|
"tennis racket",
|
|
"bottle",
|
|
"wine glass",
|
|
"cup",
|
|
"fork",
|
|
"knife",
|
|
"spoon",
|
|
"bowl",
|
|
"banana",
|
|
"apple",
|
|
"sandwich",
|
|
"orange",
|
|
"broccoli",
|
|
"carrot",
|
|
"hot dog",
|
|
"pizza",
|
|
"donut",
|
|
"cake",
|
|
"chair",
|
|
"sofa",
|
|
"pottedplant",
|
|
"bed",
|
|
"diningtable",
|
|
"toilet",
|
|
"tvmonitor",
|
|
"laptop",
|
|
"mouse",
|
|
"remote",
|
|
"keyboard",
|
|
"cell phone",
|
|
"microwave",
|
|
"oven",
|
|
"toaster",
|
|
"sink",
|
|
"refrigerator",
|
|
"book",
|
|
"clock",
|
|
"vase",
|
|
"scissors",
|
|
"teddy bear",
|
|
"hair drier",
|
|
"toothbrush",
|
|
]
|
|
|
|
def __del__(self):
|
|
self.net = None
|
|
|
|
def __call__(self, img):
|
|
img_h = img.shape[0]
|
|
img_w = img.shape[1]
|
|
|
|
mat_in = ncnn.Mat.from_pixels_resize(
|
|
img,
|
|
ncnn.Mat.PixelType.PIXEL_BGR2RGB,
|
|
img.shape[1],
|
|
img.shape[0],
|
|
self.target_size,
|
|
self.target_size,
|
|
)
|
|
mat_in.substract_mean_normalize(self.mean_vals, self.norm_vals)
|
|
|
|
ex = self.net.create_extractor()
|
|
ex.input("data", mat_in)
|
|
|
|
ret, mat_out = ex.extract("output")
|
|
|
|
objects = []
|
|
|
|
# method 1, use ncnn.Mat.row to get the result, no memory copy
|
|
for i in range(mat_out.h):
|
|
values = mat_out.row(i)
|
|
|
|
obj = Detect_Object()
|
|
obj.label = values[0]
|
|
obj.prob = values[1]
|
|
obj.rect.x = values[2] * img_w
|
|
obj.rect.y = values[3] * img_h
|
|
obj.rect.w = values[4] * img_w - obj.rect.x
|
|
obj.rect.h = values[5] * img_h - obj.rect.y
|
|
|
|
objects.append(obj)
|
|
|
|
"""
|
|
#method 2, use ncnn.Mat->numpy.array to get the result, no memory copy too
|
|
out = np.array(mat_out)
|
|
for i in range(len(out)):
|
|
values = out[i]
|
|
obj = Detect_Object()
|
|
obj.label = values[0]
|
|
obj.prob = values[1]
|
|
obj.x = values[2] * img_w
|
|
obj.y = values[3] * img_h
|
|
obj.w = values[4] * img_w - obj.x
|
|
obj.h = values[5] * img_h - obj.y
|
|
objects.append(obj)
|
|
"""
|
|
|
|
return objects
|
|
|
|
|
|
class YoloV4_Tiny(YoloV4_Base):
|
|
def __init__(self, **kwargs):
|
|
super(YoloV4_Tiny, self).__init__(True, 416, **kwargs)
|
|
|
|
|
|
class YoloV4(YoloV4_Base):
|
|
def __init__(self, **kwargs):
|
|
super(YoloV4, self).__init__(False, 608, **kwargs)
|