中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁(yè) > news >正文

織夢(mèng)做的網(wǎng)站首頁(yè)被篡改企業(yè)網(wǎng)頁(yè)

織夢(mèng)做的網(wǎng)站首頁(yè)被篡改,企業(yè)網(wǎng)頁(yè),上海新媒體營(yíng)銷公司,南昌seo營(yíng)銷查看:OpenCV系列文章目錄(持續(xù)更新中......) 上一篇:OpenCV4.9.0在Android 開(kāi)發(fā)簡(jiǎn)介 下一篇:在 MacOS 中安裝 本指南旨在幫助您在基于 Android 相機(jī)預(yù)覽的 CV 應(yīng)用程序中使用 OpenCL ?。教程是為 Android Studio 20…

?查看:OpenCV系列文章目錄(持續(xù)更新中......)

上一篇:OpenCV4.9.0在Android 開(kāi)發(fā)簡(jiǎn)介

下一篇:在 MacOS 中安裝

本指南旨在幫助您在基于 Android 相機(jī)預(yù)覽的 CV 應(yīng)用程序中使用?OpenCL ?。教程是為?Android Studio?2022.2.1 編寫的。它已使用 Ubuntu 22.04 進(jìn)行了測(cè)試。

本教程假定您已安裝并配置了以下內(nèi)容:

  • Android Studio (2022.2.1.+)
  • JDK 17
  • Android SDK
  • Android NDK (25.2.9519653+)
  • 從?github?或發(fā)布版下載 OpenCV 源代碼,并按照?wiki 上的指令構(gòu)建。

它還假定您熟悉 Android Java 和 JNI 編程基礎(chǔ)知識(shí)。如果您需要上述任何方面的幫助,可以參考我們的?Android 開(kāi)發(fā)簡(jiǎn)介指南。

本教程還假設(shè)您有一個(gè)啟用了 OpenCL 的 Android 操作設(shè)備。

相關(guān)源代碼位于?opencv/samples/android/tutorial-4-opencl?目錄下的 OpenCV 示例中。

如何使用 OpenCL 構(gòu)建自定義 OpenCV Android SDK

  1. 組裝和配置 Android OpenCL SDK。示例的 JNI 部分依賴于標(biāo)準(zhǔn)的 Khornos OpenCL 標(biāo)頭,以及 OpenCL 和 libOpenCL.so 的C++包裝器。標(biāo)準(zhǔn)的 OpenCL 標(biāo)頭可以從 OpenCV 存儲(chǔ)庫(kù)中的第三方目錄或您的 Linux 分發(fā)包中復(fù)制。C++ 包裝器可在?Github 上的官方 Khronos 存儲(chǔ)庫(kù)中找到。按以下方式將頭文件復(fù)制到教學(xué)目錄:
    cd your_path/ && mkdir ANDROID_OPENCL_SDK && mkdir ANDROID_OPENCL_SDK/include && cd ANDROID_OPENCL_SDK/include
    cp -r path_to_opencv/opencv/3rdparty/include/opencl/1.2/CL . && cd CL
    wget https://github.com/KhronosGroup/OpenCL-CLHPP/raw/main/include/CL/opencl.hpp
    wget https://github.com/KhronosGroup/OpenCL-CLHPP/raw/main/include/CL/cl2.hpp

    wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

    libOpenCL.so 可以隨 BSP 一起提供,也可以從任何具有相關(guān)架構(gòu)的 OpenCL-cabaple Android 設(shè)備下載
    cd your_path/ANDROID_OPENCL_SDK && mkdir lib && cd lib
    adb pull /system/vendor/lib64/libOpenCL.so

    wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

    ?libOpenCL.so 的系統(tǒng)版本可能有很多特定于平臺(tái)的依賴關(guān)系。-Wl,--allow-shlib-undefined 標(biāo)志允許忽略在構(gòu)建過(guò)程中未使用的第三方符號(hào)。以下 CMake 行允許將 JNI 部件鏈接到標(biāo)準(zhǔn) OpenCL,但不能將 loadLibrary 包含在應(yīng)用程序包中。系統(tǒng) OpenCL API 用于運(yùn)行時(shí)。

target_link_libraries(${target} -lOpenCL)

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

使用 OpenCL 構(gòu)建自定義 OpenCV Android SDK。默認(rèn)情況下,OpenCL 支持 (T-API) 在 Android 操作系統(tǒng)的 OpenCV 構(gòu)建中處于禁用狀態(tài)。但可以在啟用 OpenCL/T-API 的情況下在本地重建適用于 Android 的 OpenCV:CMake 的 use 選項(xiàng)。您還需要為 CMake 指定 Android OpenCL SDK: use 選項(xiàng)的路徑。如果您正在使用 OpenCV 構(gòu)建 OpenCV,請(qǐng)按照?wiki 上的說(shuō)明進(jìn)行操作。在 中設(shè)置這些 CMake 參數(shù),例如:-DWITH_OPENCL=ON-DANDROID_OPENCL_SDK=path_to_your_Android_OpenCL_SDKbuild_sdk.py.config.pyndk-18-api-level-21.config.py

ABI("3", "arm64-v8a", None, 21, cmake_vars=dict('WITH_OPENCL': 'ON', 'ANDROID_OPENCL_SDK': 'path_to_your_Android_OpenCL_SDK'))

如果您使用 cmake/ninja 構(gòu)建 OpenCV,請(qǐng)使用以下 bash 腳本(設(shè)置您的NDK_VERSION和路徑,而不是路徑示例):

cd path_to_opencv && mkdir build && cd build
export NDK_VERSION=25.2.9519653
export ANDROID_SDK=/home/user/Android/Sdk/
export ANDROID_OPENCL_SDK=/path_to_ANDROID_OPENCL_SDK/
export ANDROID_HOME=$ANDROID_SDK
export ANDROID_NDK_HOME=$ANDROID_SDK/ndk/$NDK_VERSION/
cmake -GNinja -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_HOME/build/cmake/android.toolchain.cmake -DANDROID_STL=c++_shared -DANDROID_NATIVE_API_LEVEL=24
-DANDROID_SDK=$ANDROID_SDK -DANDROID_NDK=$ANDROID_NDK_HOME -DBUILD_JAVA=ON -DANDROID_HOME=$ANDROID_SDK -DBUILD_ANDROID_EXAMPLES=ON
-DINSTALL_ANDROID_EXAMPLES=ON -DANDROID_ABI=arm64-v8a -DWITH_OPENCL=ON -DANDROID_OPENCL_SDK=$ANDROID_OPENCL_SDK ..

前言

現(xiàn)在,通過(guò) OpenCL 使用?GPGPU?來(lái)增強(qiáng)應(yīng)用程序性能是一種相當(dāng)現(xiàn)代的趨勢(shì)。一些CV算法(例如圖像過(guò)濾)在GPU上的運(yùn)行速度比在CPU上快得多。最近,它在 Android 操作系統(tǒng)上已成為可能。

對(duì)于 Android 操作的設(shè)備,最流行的 CV 應(yīng)用場(chǎng)景是在預(yù)覽模式下啟動(dòng)相機(jī),將一些 CV 算法應(yīng)用于每個(gè)幀,并顯示由該 CV 算法修改的預(yù)覽幀。

讓我們考慮一下如何在這種情況下使用 OpenCL。具體來(lái)說(shuō),讓我們嘗試兩種方式:直接調(diào)用 OpenCL API 和最近引入的 OpenCV T-API(又名透明 API)——一些 OpenCV 算法的隱式 OpenCL 加速。

應(yīng)用程序結(jié)構(gòu)

啟動(dòng) Android API 級(jí)別 11 (Android 3.0)?相機(jī) API?允許使用 OpenGL 紋理作為預(yù)覽幀的目標(biāo)。Android API 級(jí)別 21 帶來(lái)了一個(gè)新的?Camera2 API,它提供了對(duì)相機(jī)設(shè)置和使用模式的更多控制,它允許預(yù)覽幀的多個(gè)目標(biāo),特別是 OpenGL 紋理。

在 OpenGL 紋理中擁有預(yù)覽幀對(duì)于使用 OpenCL 來(lái)說(shuō)很劃算,因?yàn)橛幸粋€(gè)?OpenGL-OpenCL 互操作性 API (cl_khr_gl_sharing),允許與 OpenCL 函數(shù)共享 OpenGL 紋理數(shù)據(jù)而無(wú)需復(fù)制(當(dāng)然有一些限制)。

讓我們?yōu)槲覀兊膽?yīng)用程序創(chuàng)建一個(gè)基礎(chǔ),該基礎(chǔ)僅將 Android 相機(jī)配置為將預(yù)覽幀發(fā)送到 OpenGL 紋理,并在顯示器上顯示這些幀,而無(wú)需進(jìn)行任何處理。

用于此目的的最小類Activity如下所示:Activity

public class Tutorial4Activity extends Activity {
private MyGLSurfaceView mView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
mView = new MyGLSurfaceView(this);
setContentView(mView);
}
@Override
protected void onPause() {
mView.onPause();
super.onPause();
}
@Override
protected void onResume() {
super.onResume();
mView.onResume();
}
}

和最小的類View分別是

?
public class MyGLSurfaceView extends CameraGLSurfaceView implements CameraGLSurfaceView.CameraTextureListener {
static final String LOGTAG = "MyGLSurfaceView";
protected int procMode = NativePart.PROCESSING_MODE_NO_PROCESSING;
static final String[] procModeName = new String[] {"No Processing", "CPU", "OpenCL Direct", "OpenCL via OpenCV"};
protected int frameCounter;
protected long lastNanoTime;
TextView mFpsText = null;
public MyGLSurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onTouchEvent(MotionEvent e) {
if(e.getAction() == MotionEvent.ACTION_DOWN)
((Activity)getContext()).openOptionsMenu();
return true;
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
super.surfaceCreated(holder);
//NativePart.initCL();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
//NativePart.closeCL();
super.surfaceDestroyed(holder);
}
public void setProcessingMode(int newMode) {
if(newMode>=0 && newMode<procModeName.length)
procMode = newMode;
else
Log.e(LOGTAG, "Ignoring invalid processing mode: " + newMode);
((Activity) getContext()).runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(getContext(), "Selected mode: " + procModeName[procMode], Toast.LENGTH_LONG).show();
}
});
}
@Override
public void onCameraViewStarted(int width, int height) {
((Activity) getContext()).runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(getContext(), "onCameraViewStarted", Toast.LENGTH_SHORT).show();
}
});
if (NativePart.builtWithOpenCL())
NativePart.initCL();
frameCounter = 0;
lastNanoTime = System.nanoTime();
}
@Override
public void onCameraViewStopped() {
((Activity) getContext()).runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(getContext(), "onCameraViewStopped", Toast.LENGTH_SHORT).show();
}
});
}
@Override
public boolean onCameraTexture(int texIn, int texOut, int width, int height) {
// FPS
frameCounter++;
if(frameCounter >= 30)
{
final int fps = (int) (frameCounter * 1e9 / (System.nanoTime() - lastNanoTime));
Log.i(LOGTAG, "drawFrame() FPS: "+fps);
if(mFpsText != null) {
Runnable fpsUpdater = new Runnable() {
public void run() {
mFpsText.setText("FPS: " + fps);
}
};
new Handler(Looper.getMainLooper()).post(fpsUpdater);
} else {
Log.d(LOGTAG, "mFpsText == null");
mFpsText = (TextView)((Activity) getContext()).findViewById(R.id.fps_text_view);
}
frameCounter = 0;
lastNanoTime = System.nanoTime();
}
if(procMode == NativePart.PROCESSING_MODE_NO_PROCESSING)
return false;
NativePart.processFrame(texIn, texOut, width, height, procMode);
return true;
}
}

注意

我們使用兩個(gè)渲染器類:一個(gè)用于舊版 Camera?API,另一個(gè)用于現(xiàn)代?Camera2。

一個(gè)最小的類Renderer可以在 Java 中實(shí)現(xiàn)(OpenGL ES 2.0 在 Java?中可用),但由于我們將使用 OpenCL 修改預(yù)覽紋理,因此讓我們將 OpenGL 的東西移動(dòng)到 JNI。下面是 JNI 內(nèi)容的簡(jiǎn)單 Java 包裝器:

public class NativePart {
static
{
System.loadLibrary("opencv_java4");
System.loadLibrary("JNIpart");
}
public static final int PROCESSING_MODE_NO_PROCESSING = 0;
public static final int PROCESSING_MODE_CPU = 1;
public static final int PROCESSING_MODE_OCL_DIRECT = 2;
public static final int PROCESSING_MODE_OCL_OCV = 3;
public static native boolean builtWithOpenCL();
public static native int initCL();
public static native void closeCL();
public static native void processFrame(int tex1, int tex2, int w, int h, int mode);
}

由于 Camera?和Camera2? API 在相機(jī)設(shè)置和控制方面存在很大差異,因此讓我們?yōu)閮蓚€(gè)相應(yīng)的渲染器創(chuàng)建一個(gè)基類:

?
public abstract class MyGLRendererBase implements GLSurfaceView.Renderer, SurfaceTexture.OnFrameAvailableListener {
protected final String LOGTAG = "MyGLRendererBase";
protected SurfaceTexture mSTex;
protected MyGLSurfaceView mView;
protected boolean mGLInit = false;
protected boolean mTexUpdate = false;
MyGLRendererBase(MyGLSurfaceView view) {
mView = view;
}
protected abstract void openCamera();
protected abstract void closeCamera();
protected abstract void setCameraPreviewSize(int width, int height);
public void onResume() {
Log.i(LOGTAG, "onResume");
}
public void onPause() {
Log.i(LOGTAG, "onPause");
mGLInit = false;
mTexUpdate = false;
closeCamera();
if(mSTex != null) {
mSTex.release();
mSTex = null;
NativeGLRenderer.closeGL();
}
}
@Override
public synchronized void onFrameAvailable(SurfaceTexture surfaceTexture) {
//Log.i(LOGTAG, "onFrameAvailable");
mTexUpdate = true;
mView.requestRender();
}
@Override
public void onDrawFrame(GL10 gl) {
//Log.i(LOGTAG, "onDrawFrame");
if (!mGLInit)
return;
synchronized (this) {
if (mTexUpdate) {
mSTex.updateTexImage();
mTexUpdate = false;
}
}
NativeGLRenderer.drawFrame();
}
@Override
public void onSurfaceChanged(GL10 gl, int surfaceWidth, int surfaceHeight) {
Log.i(LOGTAG, "onSurfaceChanged("+surfaceWidth+"x"+surfaceHeight+")");
NativeGLRenderer.changeSize(surfaceWidth, surfaceHeight);
setCameraPreviewSize(surfaceWidth, surfaceHeight);
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
Log.i(LOGTAG, "onSurfaceCreated");
String strGLVersion = GLES20.glGetString(GLES20.GL_VERSION);
if (strGLVersion != null)
Log.i(LOGTAG, "OpenGL ES version: " + strGLVersion);
int hTex = NativeGLRenderer.initGL();
mSTex = new SurfaceTexture(hTex);
mSTex.setOnFrameAvailableListener(this);
openCamera();
mGLInit = true;
}
}

如您所見(jiàn),?Camera?和?Camera2? APIs的繼承者應(yīng)實(shí)現(xiàn)以下抽象方法:

protected abstract void openCamera();
protected abstract void closeCamera();
protected abstract void setCameraPreviewSize(int width, int height);

讓我們把它們實(shí)現(xiàn)的細(xì)節(jié)留給本教程之外,請(qǐng)參考源代碼查看它們。

預(yù)覽幀修改

OpenGL ES 2.0 初始化的細(xì)節(jié)也相當(dāng)簡(jiǎn)單明了,這里要引用的嘈雜,但這里重要的一點(diǎn)是,作為相機(jī)預(yù)覽目標(biāo)的 OpeGL 紋理應(yīng)該是類型(不是),在內(nèi)部它以?YUV?格式保存圖片數(shù)據(jù)。這使得無(wú)法通過(guò) CL-GL 互操作 () 共享它并通過(guò) C/C++ 代碼訪問(wèn)其像素?cái)?shù)據(jù)。為了克服這個(gè)限制,我們必須使用?FrameBuffer 對(duì)象(又名 FBO)執(zhí)行從這個(gè)紋理到另一個(gè)常規(guī)紋理的 OpenGL 渲染

OpenGL ES 2.0 初始化的細(xì)節(jié)也相當(dāng)簡(jiǎn)單明了,這里要引用的嘈雜,但這里重要的一點(diǎn)是,作為相機(jī)預(yù)覽目標(biāo)的 OpeGL 紋理應(yīng)該是類型(GL_TEXTURE_EXTERNAL_OES不是GL_TEXTURE_2D),在內(nèi)部它以?YUV?格式保存圖片數(shù)據(jù)。這使得無(wú)法通過(guò) CL-GL cl_khr_gl_sharing互操作 () 共享它并通過(guò) C/C++ 代碼訪問(wèn)其像素?cái)?shù)據(jù)。為了克服這個(gè)限制,我們必須使用?FrameBuffer 對(duì)象(又名 FBO)執(zhí)行從這個(gè)紋理GL_TEXTURE_2D到另一個(gè)常規(guī)紋理的 OpenGL 渲染。

C/C++ code

之后,我們可以從 C/C++ 讀取(?glReadPixels()復(fù)制)像素?cái)?shù)據(jù),并通過(guò)修改后將它們寫回紋理?glTexSubImage2D()

直接 OpenCL 調(diào)用

此外,該紋理可以在不復(fù)制的情況下與 OpenCL 共享,但我們必須以特殊方式創(chuàng)建 OpenCL context如下:

?
int initCL()
{
dumpCLinfo();
LOGE("initCL: start initCL");
EGLDisplay mEglDisplay = eglGetCurrentDisplay();
if (mEglDisplay == EGL_NO_DISPLAY)
LOGE("initCL: eglGetCurrentDisplay() returned 'EGL_NO_DISPLAY', error = %x", eglGetError());
EGLContext mEglContext = eglGetCurrentContext();
if (mEglContext == EGL_NO_CONTEXT)
LOGE("initCL: eglGetCurrentContext() returned 'EGL_NO_CONTEXT', error = %x", eglGetError());
cl_context_properties props[] =
{ CL_GL_CONTEXT_KHR, (cl_context_properties) mEglContext,
CL_EGL_DISPLAY_KHR, (cl_context_properties) mEglDisplay,
CL_CONTEXT_PLATFORM, 0,
0 };
try
{
haveOpenCL = false;
cl::Platform p = cl::Platform::getDefault();
std::string ext = p.getInfo<CL_PLATFORM_EXTENSIONS>();
if(ext.find("cl_khr_gl_sharing") == std::string::npos)
LOGE("Warning: CL-GL sharing isn't supported by PLATFORM");
props[5] = (cl_context_properties) p();
theContext = cl::Context(CL_DEVICE_TYPE_GPU, props);
std::vector<cl::Device> devs = theContext.getInfo<CL_CONTEXT_DEVICES>();
LOGD("Context returned %d devices, taking the 1st one", devs.size());
ext = devs[0].getInfo<CL_DEVICE_EXTENSIONS>();
if(ext.find("cl_khr_gl_sharing") == std::string::npos)
LOGE("Warning: CL-GL sharing isn't supported by DEVICE");
theQueue = cl::CommandQueue(theContext, devs[0]);
cl::Program::Sources src(1, std::make_pair(oclProgI2I, sizeof(oclProgI2I)));
theProgI2I = cl::Program(theContext, src);
theProgI2I.build(devs);
cv::ocl::attachContext(p.getInfo<CL_PLATFORM_NAME>(), p(), theContext(), devs[0]());
if( cv::ocl::useOpenCL() )
LOGD("OpenCV+OpenCL works OK!");
else
LOGE("Can't init OpenCV with OpenCL TAPI");
haveOpenCL = true;
}
catch(const cl::Error& e){
LOGE("cl::Error: %s (%d)", e.what(), e.err());
return 1;
}
catch(const std::exception& e)
{
LOGE("std::exception: %s", e.what());
return 2;
}
catch(...)
{
LOGE( "OpenCL info: unknown error while initializing OpenCL stuff" );
return 3;
}
LOGD("initCL completed");
if (haveOpenCL)
return 0;
else
return 4;
}

然后,紋理可以被對(duì)象包裝?cl::ImageGL并通過(guò) OpenCL 調(diào)用進(jìn)行處理

?cl::ImageGL imgIn (theContext, CL_MEM_READ_ONLY, GL_TEXTURE_2D, 0, texIn);
cl::ImageGL imgOut(theContext, CL_MEM_WRITE_ONLY, GL_TEXTURE_2D, 0, texOut);
std::vector < cl::Memory > images;
images.push_back(imgIn);
images.push_back(imgOut);
int64_t t = getTimeMs();
theQueue.enqueueAcquireGLObjects(&images);
theQueue.finish();
LOGD("enqueueAcquireGLObjects() costs %d ms", getTimeInterval(t));
t = getTimeMs();
cl::Kernel Laplacian(theProgI2I, "Laplacian"); //TODO: may be done once
Laplacian.setArg(0, imgIn);
Laplacian.setArg(1, imgOut);
theQueue.finish();
LOGD("Kernel() costs %d ms", getTimeInterval(t));
t = getTimeMs();
theQueue.enqueueNDRangeKernel(Laplacian, cl::NullRange, cl::NDRange(w, h), cl::NullRange);
theQueue.finish();
LOGD("enqueueNDRangeKernel() costs %d ms", getTimeInterval(t));
t = getTimeMs();
theQueue.enqueueReleaseGLObjects(&images);
theQueue.finish();
LOGD("enqueueReleaseGLObjects() costs %d ms", getTimeInterval(t));

OpenCV T-API

但是,與其自己編寫 OpenCL 代碼,不如使用隱式調(diào)用 OpenCL 的?OpenCV T-API。您只需要將創(chuàng)建的 OpenCL 上下文傳遞給 OpenCV(通過(guò)cv::ocl::attachContext() ),并以某種??cv::UMat.方式將 OpenGL 紋理包裝起來(lái)。不幸的是,OpenCL?緩沖區(qū)在內(nèi)部保留,它不能包裝在 OpenGL?紋理或 OpenCL?圖像上 - 因此我們必須在此處復(fù)制圖像數(shù)據(jù):

?int64_t t = getTimeMs();
cl::ImageGL imgIn (theContext, CL_MEM_READ_ONLY, GL_TEXTURE_2D, 0, texIn);
std::vector < cl::Memory > images(1, imgIn);
theQueue.enqueueAcquireGLObjects(&images);
theQueue.finish();
cv::UMat uIn, uOut, uTmp;
cv::ocl::convertFromImage(imgIn(), uIn);
LOGD("loading texture data to OpenCV UMat costs %d ms", getTimeInterval(t));
theQueue.enqueueReleaseGLObjects(&images);
t = getTimeMs();
//cv::blur(uIn, uOut, cv::Size(5, 5));
cv::Laplacian(uIn, uTmp, CV_8U);
cv:multiply(uTmp, 10, uOut);
cv::ocl::finish();
LOGD("OpenCV processing costs %d ms", getTimeInterval(t));
t = getTimeMs();
cl::ImageGL imgOut(theContext, CL_MEM_WRITE_ONLY, GL_TEXTURE_2D, 0, texOut);
images.clear();
images.push_back(imgOut);
theQueue.enqueueAcquireGLObjects(&images);
cl_mem clBuffer = (cl_mem)uOut.handle(cv::ACCESS_READ);
cl_command_queue q = (cl_command_queue)cv::ocl::Queue::getDefault().ptr();
size_t offset = 0;
size_t origin[3] = { 0, 0, 0 };
size_t region[3] = { (size_t)w, (size_t)h, 1 };
CV_Assert(clEnqueueCopyBufferToImage (q, clBuffer, imgOut(), offset, origin, region, 0, NULL, NULL) == CL_SUCCESS);
theQueue.enqueueReleaseGLObjects(&images);
cv::ocl::finish();
LOGD("uploading results to texture costs %d ms", getTimeInterval(t));

注意

當(dāng)通過(guò) OpenCL 圖像包裝器將修改后的圖像放回原始 OpenGL 紋理時(shí),我們必須再制作一個(gè)圖像數(shù)據(jù)副本。

性能說(shuō)明

為了比較在具有720p相機(jī)分辨率的Sony Xperia Z3上,通過(guò)C / C++代碼(調(diào)用cv::Laplacian與cv::Mat),直接OpenCL調(diào)用(使用OpenCL圖像進(jìn)行輸入和輸出)和OpenCV?T-API(調(diào)用cv::Laplacian與cv::UMat)完成的相同預(yù)覽幀修改(Laplacian)的FPS:

  • C/C++ 版本顯示?3-4 fps
  • 直接 OpenCL 調(diào)用顯示?25-27 fps
  • OpenCV T-API?顯示?11-13 fps(由于額外的來(lái)回復(fù)制)cl_imagecl_buffer

參考文獻(xiàn):

1、《Use OpenCL in Android camera preview based CV application》? Andrey Pavlenko, Alexander?Panov

http://www.risenshineclean.com/news/64473.html

相關(guān)文章:

  • 網(wǎng)加速器長(zhǎng)沙seo外包
  • 易語(yǔ)言編程可以做網(wǎng)站么杭州網(wǎng)站推廣公司
  • 建設(shè)網(wǎng)站的實(shí)驗(yàn)?zāi)康暮鸵饬xseo網(wǎng)站優(yōu)化平臺(tái)
  • 上海建設(shè)網(wǎng)站的公司b2b網(wǎng)站推廣排名
  • 申請(qǐng)網(wǎng)頁(yè)空間的網(wǎng)站搜索引擎簡(jiǎn)稱seo
  • 廣州網(wǎng)站建設(shè)制作的公司個(gè)人怎么創(chuàng)建網(wǎng)站
  • 傳奇sf 新開(kāi)網(wǎng)站百度博客收錄提交入口
  • 搜索引擎優(yōu)化的基本方法成都網(wǎng)站優(yōu)化公司
  • 新手做淘寶哪個(gè)網(wǎng)站比較好網(wǎng)絡(luò)營(yíng)銷七個(gè)步驟
  • 做網(wǎng)站用什么軟件語(yǔ)言網(wǎng)站ip查詢
  • 網(wǎng)站建設(shè)1磁力多多
  • 網(wǎng)站品牌推廣韶山seo快速排名
  • 做網(wǎng)站備案照片的要求網(wǎng)頁(yè)自助建站
  • 購(gòu)物網(wǎng)站建設(shè)平臺(tái)莆田seo推廣公司
  • 哪個(gè)網(wǎng)站可以做簡(jiǎn)歷郵件營(yíng)銷
  • 我是做裝修的怎么樣投資網(wǎng)站個(gè)人網(wǎng)站規(guī)劃書模板
  • 安陽(yáng)市網(wǎng)站建設(shè)的公司企點(diǎn)qq
  • 企業(yè)如何進(jìn)行網(wǎng)站建設(shè)產(chǎn)品網(wǎng)絡(luò)營(yíng)銷方案
  • 在百度云上建設(shè)網(wǎng)站如何把品牌推廣出去
  • 廈門網(wǎng)站建設(shè)價(jià)google應(yīng)用商店
  • 哪里有手機(jī)網(wǎng)站定制服務(wù)器手機(jī)怎么自己制作網(wǎng)頁(yè)
  • b2b網(wǎng)站黃頁(yè)怎么讓百度快速收錄網(wǎng)站
  • 如何建設(shè)阿里巴巴網(wǎng)站游戲推廣平臺(tái)
  • 青海省建設(shè)廳建管處網(wǎng)站排名點(diǎn)擊工具
  • 前端做網(wǎng)站使用的軟件工具信息流廣告是什么
  • 英文網(wǎng)站建設(shè)電話咨詢網(wǎng)頁(yè)做推廣
  • 沌口網(wǎng)站建設(shè)seo是什么品牌
  • 手機(jī)做網(wǎng)站用什么軟件深圳優(yōu)化公司哪家好
  • 網(wǎng)站功能定制優(yōu)化手機(jī)流暢度的軟件
  • 網(wǎng)站如何做搜狗搜索引擎百度下載安裝免費(fèi)