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

@ -0,0 +1,193 @@
package org.opencv.highgui;
import org.opencv.core.Mat;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
/**
* This class was designed for use in Java applications
* to recreate the OpenCV HighGui functionalities.
*/
public final class HighGui {
// Constants for namedWindow
public final static int WINDOW_NORMAL = ImageWindow.WINDOW_NORMAL;
public final static int WINDOW_AUTOSIZE = ImageWindow.WINDOW_AUTOSIZE;
// Control Variables
public static int n_closed_windows = 0;
public static int pressedKey = -1;
public static CountDownLatch latch = new CountDownLatch(1);
// Windows Map
public static Map<String, ImageWindow> windows = new HashMap<String, ImageWindow>();
public static void namedWindow(String winname) {
namedWindow(winname, HighGui.WINDOW_AUTOSIZE);
}
public static void namedWindow(String winname, int flag) {
ImageWindow newWin = new ImageWindow(winname, flag);
if (windows.get(winname) == null) windows.put(winname, newWin);
}
public static void imshow(String winname, Mat img) {
if (img.empty()) {
System.err.println("Error: Empty image in imshow");
System.exit(-1);
} else {
ImageWindow tmpWindow = windows.get(winname);
if (tmpWindow == null) {
ImageWindow newWin = new ImageWindow(winname, img);
windows.put(winname, newWin);
} else {
tmpWindow.setMat(img);
}
}
}
public static Image toBufferedImage(Mat m) {
int type = BufferedImage.TYPE_BYTE_GRAY;
if (m.channels() > 1) {
type = BufferedImage.TYPE_3BYTE_BGR;
}
int bufferSize = m.channels() * m.cols() * m.rows();
byte[] b = new byte[bufferSize];
m.get(0, 0, b); // get all the pixels
BufferedImage image = new BufferedImage(m.cols(), m.rows(), type);
final byte[] targetPixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
System.arraycopy(b, 0, targetPixels, 0, b.length);
return image;
}
public static JFrame createJFrame(String title, int flag) {
JFrame frame = new JFrame(title);
frame.addWindowListener(new java.awt.event.WindowAdapter() {
@Override
public void windowClosing(java.awt.event.WindowEvent windowEvent) {
n_closed_windows++;
if (n_closed_windows == windows.size()) latch.countDown();
}
});
frame.addKeyListener(new KeyListener() {
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
pressedKey = e.getKeyCode();
latch.countDown();
}
});
if (flag == WINDOW_AUTOSIZE) frame.setResizable(false);
return frame;
}
public static void waitKey(){
waitKey(0);
}
public static int waitKey(int delay) {
// Reset control values
latch = new CountDownLatch(1);
n_closed_windows = 0;
pressedKey = -1;
// If there are no windows to be shown return
if (windows.isEmpty()) {
System.err.println("Error: waitKey must be used after an imshow");
System.exit(-1);
}
// Remove the unused windows
Iterator<Map.Entry<String,
ImageWindow>> iter = windows.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry<String,
ImageWindow> entry = iter.next();
ImageWindow win = entry.getValue();
if (win.alreadyUsed) {
iter.remove();
win.frame.dispose();
}
}
// (if) Create (else) Update frame
for (ImageWindow win : windows.values()) {
if (win.img != null) {
ImageIcon icon = new ImageIcon(toBufferedImage(win.img));
if (win.lbl == null) {
JFrame frame = createJFrame(win.name, win.flag);
JLabel lbl = new JLabel(icon);
win.setFrameLabelVisible(frame, lbl);
} else {
win.lbl.setIcon(icon);
}
} else {
System.err.println("Error: no imshow associated with" + " namedWindow: \"" + win.name + "\"");
System.exit(-1);
}
}
try {
if (delay == 0) {
latch.await();
} else {
latch.await(delay, TimeUnit.MILLISECONDS);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
// Set all windows as already used
for (ImageWindow win : windows.values())
win.alreadyUsed = true;
return pressedKey;
}
public static void destroyWindow(String winname) {
ImageWindow tmpWin = windows.get(winname);
if (tmpWin != null) windows.remove(winname);
}
public static void destroyAllWindows() {
windows.clear();
}
public static void resizeWindow(String winname, int width, int height) {
ImageWindow tmpWin = windows.get(winname);
if (tmpWin != null) tmpWin.setNewDimension(width, height);
}
public static void moveWindow(String winname, int x, int y) {
ImageWindow tmpWin = windows.get(winname);
if (tmpWin != null) tmpWin.setNewPosition(x, y);
}
}

View File

@ -0,0 +1,132 @@
package org.opencv.highgui;
import org.opencv.core.Mat;
import org.opencv.core.Size;
import org.opencv.imgproc.Imgproc;
import javax.swing.*;
import java.awt.*;
/**
* This class was designed to create and manipulate
* the Windows to be used by the HighGui class.
*/
public final class ImageWindow {
public final static int WINDOW_NORMAL = 0;
public final static int WINDOW_AUTOSIZE = 1;
public String name;
public Mat img = null;
public Boolean alreadyUsed = false;
public Boolean imgToBeResized = false;
public Boolean windowToBeResized = false;
public Boolean positionToBeChanged = false;
public JFrame frame = null;
public JLabel lbl = null;
public int flag;
public int x = -1;
public int y = -1;
public int width = -1;
public int height = -1;
public ImageWindow(String name, Mat img) {
this.name = name;
this.img = img;
this.flag = WINDOW_NORMAL;
}
public ImageWindow(String name, int flag) {
this.name = name;
this.flag = flag;
}
public static Size keepAspectRatioSize(int original_width, int original_height, int bound_width, int bound_height) {
int new_width = original_width;
int new_height = original_height;
if (original_width > bound_width) {
new_width = bound_width;
new_height = (new_width * original_height) / original_width;
}
if (new_height > bound_height) {
new_height = bound_height;
new_width = (new_height * original_width) / original_height;
}
return new Size(new_width, new_height);
}
public void setMat(Mat img) {
this.img = img;
this.alreadyUsed = false;
if (imgToBeResized) {
resizeImage();
imgToBeResized = false;
}
}
public void setFrameLabelVisible(JFrame frame, JLabel lbl) {
this.frame = frame;
this.lbl = lbl;
if (windowToBeResized) {
lbl.setPreferredSize(new Dimension(width, height));
windowToBeResized = false;
}
if (positionToBeChanged) {
frame.setLocation(x, y);
positionToBeChanged = false;
}
frame.add(lbl);
frame.pack();
frame.setVisible(true);
}
public void setNewDimension(int width, int height) {
if (this.width != width || this.height != height) {
this.width = width;
this.height = height;
if (img != null) {
resizeImage();
} else {
imgToBeResized = true;
}
if (lbl != null) {
lbl.setPreferredSize(new Dimension(width, height));
} else {
windowToBeResized = true;
}
}
}
public void setNewPosition(int x, int y) {
if (this.x != x || this.y != y) {
this.x = x;
this.y = y;
if (frame != null) {
frame.setLocation(x, y);
} else {
positionToBeChanged = true;
}
}
}
private void resizeImage() {
if (flag == WINDOW_NORMAL) {
Size tmpSize = keepAspectRatioSize(img.width(), img.height(), width, height);
Imgproc.resize(img, img, tmpSize, 0, 0, Imgproc.INTER_LINEAR_EXACT);
}
}
}

View File

@ -0,0 +1,72 @@
#!/bin/bash
set -e
if [ -z $1 ] ; then
echo "$0 <destination directory>"
exit 1
fi
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
OCV="$( cd "${DIR}/../../../.." >/dev/null 2>&1 && pwd )"
mkdir -p "${1}" # Docker creates non-existed mounts with 'root' owner, lets ensure that dir exists under the current user to avoid "Permission denied" problem
DST="$( cd "$1" >/dev/null 2>&1 && pwd )"
CFG=${2:-Release}
do_build()
{
TAG=$1
D=$2
F=$3
shift 3
docker build \
--build-arg http_proxy \
--build-arg https_proxy \
$@ \
-t $TAG \
-f "${D}/${F}" \
"${D}"
}
do_run()
{
TAG=$1
shift 1
docker run \
-it \
--rm \
-v "${OCV}":/opencv:ro \
-v "${DST}":/dst \
-e CFG=$CFG \
--user $(id -u):$(id -g) \
$TAG \
"$@"
}
build_gtk2_ubuntu()
{
VER=$1
shift 1
TAG=opencv_highgui_ubuntu_gtk2_builder:${VER}
do_build $TAG "${DIR}/plugin_gtk" Dockerfile-ubuntu-gtk2 --build-arg VER=${VER}
do_run $TAG /opencv/modules/highgui/misc/plugins/plugin_gtk/build.sh /dst gtk2_ubuntu${VER} ${CFG} "$@"
}
build_gtk3_ubuntu()
{
VER=$1
shift 1
TAG=opencv_highgui_ubuntu_gtk3_builder:${VER}
do_build $TAG "${DIR}/plugin_gtk" Dockerfile-ubuntu-gtk3 --build-arg VER=${VER}
do_run $TAG /opencv/modules/highgui/misc/plugins/plugin_gtk/build.sh /dst gtk3_ubuntu${VER} ${CFG} "$@"
}
echo "OpenCV: ${OCV}"
echo "Destination: ${DST}"
build_gtk2_ubuntu 16.04
build_gtk2_ubuntu 16.04 -DOPENCV_PLUGIN_NAME=opencv_highgui_gtk2-opengl_ubuntu16.04 -DWITH_OPENGL=ON -DWITH_GTK_2_X=ON
build_gtk2_ubuntu 18.04
build_gtk3_ubuntu 18.04
build_gtk3_ubuntu 20.04

View File

@ -0,0 +1,58 @@
cmake_minimum_required(VERSION 3.5)
project(opencv_highgui_gtk)
get_filename_component(OpenCV_SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/../../../../.." ABSOLUTE)
include("${OpenCV_SOURCE_DIR}/cmake/OpenCVPluginStandalone.cmake")
# scan dependencies
set(WITH_GTK ON)
include("${OpenCV_SOURCE_DIR}/modules/highgui/cmake/init.cmake")
if(NOT HAVE_GTK)
message(FATAL_ERROR "GTK: NO")
endif()
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wno-deprecated-declarations)
set(OPENCV_PLUGIN_DEPS core imgproc imgcodecs)
if(TARGET ocv.3rdparty.gtk3)
set(__deps ocv.3rdparty.gtk3)
elseif(TARGET ocv.3rdparty.gtk2)
set(__deps ocv.3rdparty.gtk2)
elseif(TARGET ocv.3rdparty.gtk)
set(__deps ocv.3rdparty.gtk)
else()
message(FATAL_ERROR "Missing dependency target for GTK libraries")
endif()
ocv_create_plugin(highgui "opencv_highgui_gtk" "${__deps}" "GTK" "src/window_gtk.cpp")
if(WITH_OPENGL)
if(HAVE_GTK2
AND TARGET ocv.3rdparty.gtkglext
AND TARGET ocv.3rdparty.gtk_opengl
AND NOT OPENCV_GTK_DISABLE_GTKGLEXT
AND NOT OPENCV_GTK_DISABLE_OPENGL
)
message(STATUS "OpenGL: YES")
target_link_libraries(${OPENCV_PLUGIN_NAME} PRIVATE
ocv.3rdparty.gtkglext ocv.3rdparty.gtk_opengl
)
else()
message(WARNING "OpenGL dependencies are not available!")
endif()
endif()
if(HAVE_GTK3)
message(STATUS "GTK3+: ver ${GTK3_VERSION}")
elseif(HAVE_GTK3)
message(STATUS "GTK2+: ver ${GTK2_VERSION}")
elseif(DEFINED GTK_VERSION)
message(STATUS "GTK+: ver ${GTK_VERSION}")
else()
message(STATUS "GTK+: YES")
endif()
if(HAVE_GTHREAD)
message(STATUS "GThread : YES (ver ${GTHREAD_VERSION})")
else()
message(STATUS "GThread : NO")
endif()

View File

@ -0,0 +1,28 @@
ARG VER
FROM ubuntu:$VER
RUN \
apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
pkg-config \
cmake \
g++ \
ninja-build \
&& \
rm -rf /var/lib/apt/lists/*
RUN \
apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
libgtk2.0-dev \
&& \
rm -rf /var/lib/apt/lists/*
RUN \
apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
libgtkglext1-dev \
&& \
rm -rf /var/lib/apt/lists/*
WORKDIR /tmp

View File

@ -0,0 +1,21 @@
ARG VER
FROM ubuntu:$VER
RUN \
apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
pkg-config \
cmake \
g++ \
ninja-build \
&& \
rm -rf /var/lib/apt/lists/*
RUN \
apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
libgtk-3-dev \
&& \
rm -rf /var/lib/apt/lists/*
WORKDIR /tmp

View File

@ -0,0 +1,21 @@
#!/bin/bash
set -e
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
OPENCV_PLUGIN_DESTINATION=$1
OPENCV_PLUGIN_NAME=opencv_highgui_$2
CMAKE_BUILD_TYPE=${3:-Release}
shift 3 || true
set -x
cmake -GNinja \
-DOPENCV_PLUGIN_NAME=${OPENCV_PLUGIN_NAME} \
-DOPENCV_PLUGIN_DESTINATION=${OPENCV_PLUGIN_DESTINATION} \
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} \
"$@" \
$DIR
ninja -v