feat: 切换后端至PaddleOCR-NCNN,切换工程为CMake
1.项目后端整体迁移至PaddleOCR-NCNN算法,已通过基本的兼容性测试 2.工程改为使用CMake组织,后续为了更好地兼容第三方库,不再提供QMake工程 3.重整权利声明文件,重整代码工程,确保最小化侵权风险 Log: 切换后端至PaddleOCR-NCNN,切换工程为CMake Change-Id: I4d5d2c5d37505a4a24b389b1a4c5d12f17bfa38c
This commit is contained in:
34
3rdparty/opencv-4.5.4/samples/android/15-puzzle/AndroidManifest.xml
vendored
Normal file
34
3rdparty/opencv-4.5.4/samples/android/15-puzzle/AndroidManifest.xml
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.opencv.samples.puzzle15"
|
||||
android:versionCode="301"
|
||||
android:versionName="3.01" >
|
||||
|
||||
<uses-sdk android:minSdkVersion="8"/>
|
||||
|
||||
<application
|
||||
android:icon="@drawable/icon"
|
||||
android:label="@string/app_name" >
|
||||
|
||||
<activity
|
||||
android:name=".Puzzle15Activity"
|
||||
android:label="@string/app_name"
|
||||
android:screenOrientation="landscape"
|
||||
android:configChanges="keyboardHidden|orientation" >
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
<uses-permission android:name="android.permission.CAMERA"/>
|
||||
|
||||
<uses-feature android:name="android.hardware.camera" android:required="false"/>
|
||||
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false"/>
|
||||
<uses-feature android:name="android.hardware.camera.front" android:required="false"/>
|
||||
<uses-feature android:name="android.hardware.camera.front.autofocus" android:required="false"/>
|
||||
|
||||
</manifest>
|
6
3rdparty/opencv-4.5.4/samples/android/15-puzzle/CMakeLists.txt
vendored
Normal file
6
3rdparty/opencv-4.5.4/samples/android/15-puzzle/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
set(sample example-15-puzzle)
|
||||
|
||||
add_android_project(${sample} "${CMAKE_CURRENT_SOURCE_DIR}" LIBRARY_DEPS "${OPENCV_ANDROID_LIB_DIR}" SDK_TARGET 11 "${ANDROID_SDK_TARGET}")
|
||||
if(TARGET ${sample})
|
||||
add_dependencies(opencv_android_examples ${sample})
|
||||
endif()
|
31
3rdparty/opencv-4.5.4/samples/android/15-puzzle/build.gradle.in
vendored
Normal file
31
3rdparty/opencv-4.5.4/samples/android/15-puzzle/build.gradle.in
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
compileSdkVersion @ANDROID_COMPILE_SDK_VERSION@
|
||||
defaultConfig {
|
||||
applicationId "org.opencv.samples.puzzle15"
|
||||
minSdkVersion @ANDROID_MIN_SDK_VERSION@
|
||||
targetSdkVersion @ANDROID_TARGET_SDK_VERSION@
|
||||
versionCode 301
|
||||
versionName "3.01"
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
sourceSets {
|
||||
main {
|
||||
java.srcDirs = @ANDROID_SAMPLE_JAVA_PATH@
|
||||
aidl.srcDirs = @ANDROID_SAMPLE_JAVA_PATH@
|
||||
res.srcDirs = @ANDROID_SAMPLE_RES_PATH@
|
||||
manifest.srcFile '@ANDROID_SAMPLE_MANIFEST_PATH@'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
//implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
implementation project(':opencv')
|
||||
}
|
31
3rdparty/opencv-4.5.4/samples/android/15-puzzle/gradle/AndroidManifest.xml
vendored
Normal file
31
3rdparty/opencv-4.5.4/samples/android/15-puzzle/gradle/AndroidManifest.xml
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.opencv.samples.puzzle15"
|
||||
>
|
||||
|
||||
<application
|
||||
android:icon="@drawable/icon"
|
||||
android:label="@string/app_name">
|
||||
|
||||
<activity
|
||||
android:name=".Puzzle15Activity"
|
||||
android:label="@string/app_name"
|
||||
android:screenOrientation="landscape"
|
||||
android:configChanges="keyboardHidden|orientation" >
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
<uses-permission android:name="android.permission.CAMERA"/>
|
||||
|
||||
<uses-feature android:name="android.hardware.camera" android:required="false"/>
|
||||
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false"/>
|
||||
<uses-feature android:name="android.hardware.camera.front" android:required="false"/>
|
||||
<uses-feature android:name="android.hardware.camera.front.autofocus" android:required="false"/>
|
||||
|
||||
</manifest>
|
BIN
3rdparty/opencv-4.5.4/samples/android/15-puzzle/res/drawable/icon.png
vendored
Normal file
BIN
3rdparty/opencv-4.5.4/samples/android/15-puzzle/res/drawable/icon.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.0 KiB |
6
3rdparty/opencv-4.5.4/samples/android/15-puzzle/res/values/strings.xml
vendored
Normal file
6
3rdparty/opencv-4.5.4/samples/android/15-puzzle/res/values/strings.xml
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
<resources>
|
||||
<string name="app_name">OCV 15 Puzzle</string>
|
||||
<string name="menu_toggle_tile_numbers">Show/hide tile numbers</string>
|
||||
<string name="menu_start_new_game">Start new game</string>
|
||||
|
||||
</resources>
|
@ -0,0 +1,153 @@
|
||||
package org.opencv.samples.puzzle15;
|
||||
|
||||
import org.opencv.android.BaseLoaderCallback;
|
||||
import org.opencv.android.CameraActivity;
|
||||
import org.opencv.android.LoaderCallbackInterface;
|
||||
import org.opencv.android.OpenCVLoader;
|
||||
import org.opencv.core.Mat;
|
||||
import org.opencv.android.CameraBridgeViewBase;
|
||||
import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener;
|
||||
import org.opencv.android.JavaCameraView;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class Puzzle15Activity extends CameraActivity implements CvCameraViewListener, View.OnTouchListener {
|
||||
|
||||
private static final String TAG = "Puzzle15::Activity";
|
||||
|
||||
private CameraBridgeViewBase mOpenCvCameraView;
|
||||
private Puzzle15Processor mPuzzle15;
|
||||
private MenuItem mItemHideNumbers;
|
||||
private MenuItem mItemStartNewGame;
|
||||
|
||||
|
||||
private int mGameWidth;
|
||||
private int mGameHeight;
|
||||
|
||||
private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
|
||||
|
||||
@Override
|
||||
public void onManagerConnected(int status) {
|
||||
switch (status) {
|
||||
case LoaderCallbackInterface.SUCCESS:
|
||||
{
|
||||
Log.i(TAG, "OpenCV loaded successfully");
|
||||
|
||||
/* Now enable camera view to start receiving frames */
|
||||
mOpenCvCameraView.setOnTouchListener(Puzzle15Activity.this);
|
||||
mOpenCvCameraView.enableView();
|
||||
} break;
|
||||
default:
|
||||
{
|
||||
super.onManagerConnected(status);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||
|
||||
Log.d(TAG, "Creating and setting view");
|
||||
mOpenCvCameraView = (CameraBridgeViewBase) new JavaCameraView(this, -1);
|
||||
setContentView(mOpenCvCameraView);
|
||||
mOpenCvCameraView.setVisibility(CameraBridgeViewBase.VISIBLE);
|
||||
mOpenCvCameraView.setCvCameraViewListener(this);
|
||||
mPuzzle15 = new Puzzle15Processor();
|
||||
mPuzzle15.prepareNewGame();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause()
|
||||
{
|
||||
super.onPause();
|
||||
if (mOpenCvCameraView != null)
|
||||
mOpenCvCameraView.disableView();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume()
|
||||
{
|
||||
super.onResume();
|
||||
if (!OpenCVLoader.initDebug()) {
|
||||
Log.d(TAG, "Internal OpenCV library not found. Using OpenCV Manager for initialization");
|
||||
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_0_0, this, mLoaderCallback);
|
||||
} else {
|
||||
Log.d(TAG, "OpenCV library found inside package. Using it!");
|
||||
mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<? extends CameraBridgeViewBase> getCameraViewList() {
|
||||
return Collections.singletonList(mOpenCvCameraView);
|
||||
}
|
||||
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (mOpenCvCameraView != null)
|
||||
mOpenCvCameraView.disableView();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
Log.i(TAG, "called onCreateOptionsMenu");
|
||||
mItemHideNumbers = menu.add("Show/hide tile numbers");
|
||||
mItemStartNewGame = menu.add("Start new game");
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
Log.i(TAG, "Menu Item selected " + item);
|
||||
if (item == mItemStartNewGame) {
|
||||
/* We need to start new game */
|
||||
mPuzzle15.prepareNewGame();
|
||||
} else if (item == mItemHideNumbers) {
|
||||
/* We need to enable or disable drawing of the tile numbers */
|
||||
mPuzzle15.toggleTileNumbers();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void onCameraViewStarted(int width, int height) {
|
||||
mGameWidth = width;
|
||||
mGameHeight = height;
|
||||
mPuzzle15.prepareGameSize(width, height);
|
||||
}
|
||||
|
||||
public void onCameraViewStopped() {
|
||||
}
|
||||
|
||||
public boolean onTouch(View view, MotionEvent event) {
|
||||
int xpos, ypos;
|
||||
|
||||
xpos = (view.getWidth() - mGameWidth) / 2;
|
||||
xpos = (int)event.getX() - xpos;
|
||||
|
||||
ypos = (view.getHeight() - mGameHeight) / 2;
|
||||
ypos = (int)event.getY() - ypos;
|
||||
|
||||
if (xpos >=0 && xpos <= mGameWidth && ypos >=0 && ypos <= mGameHeight) {
|
||||
/* click is inside the picture. Deliver this event to processor */
|
||||
mPuzzle15.deliverTouchEvent(xpos, ypos);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public Mat onCameraFrame(Mat inputFrame) {
|
||||
return mPuzzle15.puzzleFrame(inputFrame);
|
||||
}
|
||||
}
|
@ -0,0 +1,195 @@
|
||||
package org.opencv.samples.puzzle15;
|
||||
|
||||
import org.opencv.core.Core;
|
||||
import org.opencv.core.CvType;
|
||||
import org.opencv.core.Mat;
|
||||
import org.opencv.core.Scalar;
|
||||
import org.opencv.core.Size;
|
||||
import org.opencv.core.Point;
|
||||
import org.opencv.imgproc.Imgproc;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
|
||||
/**
|
||||
* This class is a controller for puzzle game.
|
||||
* It converts the image from Camera into the shuffled image
|
||||
*/
|
||||
public class Puzzle15Processor {
|
||||
|
||||
private static final int GRID_SIZE = 4;
|
||||
private static final int GRID_AREA = GRID_SIZE * GRID_SIZE;
|
||||
private static final int GRID_EMPTY_INDEX = GRID_AREA - 1;
|
||||
private static final String TAG = "Puzzle15Processor";
|
||||
private static final Scalar GRID_EMPTY_COLOR = new Scalar(0x33, 0x33, 0x33, 0xFF);
|
||||
|
||||
private int[] mIndexes;
|
||||
private int[] mTextWidths;
|
||||
private int[] mTextHeights;
|
||||
|
||||
private Mat mRgba15;
|
||||
private Mat[] mCells15;
|
||||
private boolean mShowTileNumbers = true;
|
||||
|
||||
public Puzzle15Processor() {
|
||||
mTextWidths = new int[GRID_AREA];
|
||||
mTextHeights = new int[GRID_AREA];
|
||||
|
||||
mIndexes = new int [GRID_AREA];
|
||||
|
||||
for (int i = 0; i < GRID_AREA; i++)
|
||||
mIndexes[i] = i;
|
||||
}
|
||||
|
||||
/* this method is intended to make processor prepared for a new game */
|
||||
public synchronized void prepareNewGame() {
|
||||
do {
|
||||
shuffle(mIndexes);
|
||||
} while (!isPuzzleSolvable());
|
||||
}
|
||||
|
||||
/* This method is to make the processor know the size of the frames that
|
||||
* will be delivered via puzzleFrame.
|
||||
* If the frames will be different size - then the result is unpredictable
|
||||
*/
|
||||
public synchronized void prepareGameSize(int width, int height) {
|
||||
mRgba15 = new Mat(height, width, CvType.CV_8UC4);
|
||||
mCells15 = new Mat[GRID_AREA];
|
||||
|
||||
for (int i = 0; i < GRID_SIZE; i++) {
|
||||
for (int j = 0; j < GRID_SIZE; j++) {
|
||||
int k = i * GRID_SIZE + j;
|
||||
mCells15[k] = mRgba15.submat(i * height / GRID_SIZE, (i + 1) * height / GRID_SIZE, j * width / GRID_SIZE, (j + 1) * width / GRID_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < GRID_AREA; i++) {
|
||||
Size s = Imgproc.getTextSize(Integer.toString(i + 1), 3/* CV_FONT_HERSHEY_COMPLEX */, 1, 2, null);
|
||||
mTextHeights[i] = (int) s.height;
|
||||
mTextWidths[i] = (int) s.width;
|
||||
}
|
||||
}
|
||||
|
||||
/* this method to be called from the outside. it processes the frame and shuffles
|
||||
* the tiles as specified by mIndexes array
|
||||
*/
|
||||
public synchronized Mat puzzleFrame(Mat inputPicture) {
|
||||
Mat[] cells = new Mat[GRID_AREA];
|
||||
int rows = inputPicture.rows();
|
||||
int cols = inputPicture.cols();
|
||||
|
||||
rows = rows - rows%4;
|
||||
cols = cols - cols%4;
|
||||
|
||||
for (int i = 0; i < GRID_SIZE; i++) {
|
||||
for (int j = 0; j < GRID_SIZE; j++) {
|
||||
int k = i * GRID_SIZE + j;
|
||||
cells[k] = inputPicture.submat(i * inputPicture.rows() / GRID_SIZE, (i + 1) * inputPicture.rows() / GRID_SIZE, j * inputPicture.cols()/ GRID_SIZE, (j + 1) * inputPicture.cols() / GRID_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
rows = rows - rows%4;
|
||||
cols = cols - cols%4;
|
||||
|
||||
// copy shuffled tiles
|
||||
for (int i = 0; i < GRID_AREA; i++) {
|
||||
int idx = mIndexes[i];
|
||||
if (idx == GRID_EMPTY_INDEX)
|
||||
mCells15[i].setTo(GRID_EMPTY_COLOR);
|
||||
else {
|
||||
cells[idx].copyTo(mCells15[i]);
|
||||
if (mShowTileNumbers) {
|
||||
Imgproc.putText(mCells15[i], Integer.toString(1 + idx), new Point((cols / GRID_SIZE - mTextWidths[idx]) / 2,
|
||||
(rows / GRID_SIZE + mTextHeights[idx]) / 2), 3/* CV_FONT_HERSHEY_COMPLEX */, 1, new Scalar(255, 0, 0, 255), 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < GRID_AREA; i++)
|
||||
cells[i].release();
|
||||
|
||||
drawGrid(cols, rows, mRgba15);
|
||||
|
||||
return mRgba15;
|
||||
}
|
||||
|
||||
public void toggleTileNumbers() {
|
||||
mShowTileNumbers = !mShowTileNumbers;
|
||||
}
|
||||
|
||||
public void deliverTouchEvent(int x, int y) {
|
||||
int rows = mRgba15.rows();
|
||||
int cols = mRgba15.cols();
|
||||
|
||||
int row = (int) Math.floor(y * GRID_SIZE / rows);
|
||||
int col = (int) Math.floor(x * GRID_SIZE / cols);
|
||||
|
||||
if (row < 0 || row >= GRID_SIZE || col < 0 || col >= GRID_SIZE) {
|
||||
Log.e(TAG, "It is not expected to get touch event outside of picture");
|
||||
return ;
|
||||
}
|
||||
|
||||
int idx = row * GRID_SIZE + col;
|
||||
int idxtoswap = -1;
|
||||
|
||||
// left
|
||||
if (idxtoswap < 0 && col > 0)
|
||||
if (mIndexes[idx - 1] == GRID_EMPTY_INDEX)
|
||||
idxtoswap = idx - 1;
|
||||
// right
|
||||
if (idxtoswap < 0 && col < GRID_SIZE - 1)
|
||||
if (mIndexes[idx + 1] == GRID_EMPTY_INDEX)
|
||||
idxtoswap = idx + 1;
|
||||
// top
|
||||
if (idxtoswap < 0 && row > 0)
|
||||
if (mIndexes[idx - GRID_SIZE] == GRID_EMPTY_INDEX)
|
||||
idxtoswap = idx - GRID_SIZE;
|
||||
// bottom
|
||||
if (idxtoswap < 0 && row < GRID_SIZE - 1)
|
||||
if (mIndexes[idx + GRID_SIZE] == GRID_EMPTY_INDEX)
|
||||
idxtoswap = idx + GRID_SIZE;
|
||||
|
||||
// swap
|
||||
if (idxtoswap >= 0) {
|
||||
synchronized (this) {
|
||||
int touched = mIndexes[idx];
|
||||
mIndexes[idx] = mIndexes[idxtoswap];
|
||||
mIndexes[idxtoswap] = touched;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void drawGrid(int cols, int rows, Mat drawMat) {
|
||||
for (int i = 1; i < GRID_SIZE; i++) {
|
||||
Imgproc.line(drawMat, new Point(0, i * rows / GRID_SIZE), new Point(cols, i * rows / GRID_SIZE), new Scalar(0, 255, 0, 255), 3);
|
||||
Imgproc.line(drawMat, new Point(i * cols / GRID_SIZE, 0), new Point(i * cols / GRID_SIZE, rows), new Scalar(0, 255, 0, 255), 3);
|
||||
}
|
||||
}
|
||||
|
||||
private static void shuffle(int[] array) {
|
||||
for (int i = array.length; i > 1; i--) {
|
||||
int temp = array[i - 1];
|
||||
int randIx = (int) (Math.random() * i);
|
||||
array[i - 1] = array[randIx];
|
||||
array[randIx] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isPuzzleSolvable() {
|
||||
|
||||
int sum = 0;
|
||||
for (int i = 0; i < GRID_AREA; i++) {
|
||||
if (mIndexes[i] == GRID_EMPTY_INDEX)
|
||||
sum += (i / GRID_SIZE) + 1;
|
||||
else {
|
||||
int smaller = 0;
|
||||
for (int j = i + 1; j < GRID_AREA; j++) {
|
||||
if (mIndexes[j] < mIndexes[i])
|
||||
smaller++;
|
||||
}
|
||||
sum += smaller;
|
||||
}
|
||||
}
|
||||
return sum % 2 == 0;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user