当前位置:首页 » 安卓系统 » androidopencvmat

androidopencvmat

发布时间: 2023-01-30 10:02:35

❶ opencv4android 中的2个Mat(Mat的值为2个Bitmap)如何变成一个Mat(即图片融合)

用Core里面的add或者addweighted来写

❷ 如何在Android中使用OpenCV

1、下载
进入官网下载OpenCV4Android并解压

其中,sdk目录即是我们开发opencv所需要的类库;samples目录中存放着若干opencv应用示例(包括人脸检测等),可为我们进行android下的opencv开发提供参考;doc目录为opencv类库的使用说明及api文档等;而apk目录则存放着对应于各内核版本的OpenCV_2.4.3.2_Manager_2.4应用安装包。此应用用来管理手机设备中的opencv类库,在运行opencv应用之前,必须确保手机中已经安装了OpenCV_2.4.3.2_Manager_2.4_*.apk,否则opencv应用将会因为无法加载opencv类库而无法运行(下篇文章会介绍不提前安装openCV Manager,即可运行openCV的方法)。
2、将OpenCV引入Android Studio
在Android Studio中选择File->Import Mole,找到OpenCV解压的路径,选择sdk/java文件夹

3、更新build.gradle信息
在Android Studio中的左上角选择Project视图,在oepnCVLibrary2411文件夹里,打开build.gradle(有很多重名的文件,一定找对openCV库文件下的),修改文件中的1)compileSdkVersion 2)buildToolsVersion 3) minSdkVersion 4)targetSdkVersion,将其内容与app文件夹下的build.gradle中信息相一致。点击上方提示的黄色提示框内的Try Again进行更新。
4、添加Mole Dependency
右键app文件夹,选择Open Mole Settings,在app mole的Dependencies一栏中,点击右上角的绿色加号,将openCVLibrary2411添加进去,点击确定。

5、复制libs文件夹到项目中
在OpenCV的解压包中,将sdk-->native-->libs文件夹复制,粘贴在Project视图下app-->src-->main目录下,并将其重命名为jniLibs。
自此,OpenCV的环境就配置好了。可以将OpenCV-android-sdk-->samples-->tutorial-1-camerapreview中的layout文件,java文件,放入工程中,修改AndroidManifest.xml,添加使用摄像机的权限,即可测试是否成功了。

❸ android opencv 怎么训练模型

使用 Mat 中对矩阵元素的地址定位的知识 (参考博文:OpenCV中对Mat里面depth,dims,channels,step,data,elemSize和数据地址计算的理解) Code 1 : int main() { //新建一个uchar类型的单通道矩阵(grayscale image 灰度图) Mat m(400, 400, CV_8U, Scalar(0)); for (int col = 0; col < 400; col++) { for (int row = 195; row < 205; row++) { cout << (int)(*(m.data + m.step[0] * row + m.step[1] * col)) << " ==> "; //获取第[row,col]个像素点的地址并用 * 符号解析 *(m.data + m.step[0] * row + m.step[1] * col) = 255; cout << (int)(*(m.data + m.step[0] * row + m.step[1] * col)) << endl; } } imshow("canvas", m); cvWaitKey(); return 0; } Output 1 : 0 ==> 255 0 ==> 255 0 ==> 255 0 ==> 255 0 ==> 255 0 ==> 255 ... Code1只是演示了单通道的情况,对于多通道的例子,请看 Code2 然后再看 Code3。 Fn 2 : 使用 Mat::at 函数 原型 template<typename _Tp> inline _Tp& Mat::at(…) //其中参数有多个,也就是说 at 函数有多个重载 返回值为 Mat 类型, Mat 有个索引的重载,也就是 [] 符号的重载,用这个重载可以定位多通道数据,具体示例可以看下面代码 下面的代码把红色通道值大于128的颜色的置为白色,左边为原图,右边为处理过后的图。

❹ opencv for android中mat的第4通道值用什么表示

四个通道分别是啥?是否对应。
你原来图片是什么类型?一般是32位3通道。。
我估计你是这个问题:
..com/link?url=pDZfq55c98K0f_EGgfNMwpI-fvQjEb0gciY4N_

可以先按照原本的格式读取进来,然后cvConvert。。。

新建一个目标模板即可。

❺ 如何在Android中使用OpenCV

有两种方式
1.使用OpenCV Java API。
OpenCV安装路径"F:\OpenCV-2.3.1-android-bin"下有两个文件夹, 将文件夹"OpenCV-2.3.1"拷贝到你的Eclipse工作空间所在的目录,也就是在你的项目的上一级目录中,然后导入到工作空间中,在Package Explorer中选择你的项目,单机右键在弹出菜单中选择Properties,然后在弹出的Properties窗口中左侧选择Android,然后点击右下方的Add按钮,选择OpenCV-2.3.1并点击OK,此时,展开你的项目树,你可以看到新加了一个OpenCV-2.3.1_src目录, 那么就是正确添加了OpenCV Java API,否则就是你放置OpenCV-2.3.1的目录路径不正确。然后就可以在你的Java源文件中导入OpenCV的API包,并且使用OpenCV API了,OpenCV API的包的形式如下:
Org.opencv.(OpenCV模块名).(OpenCV类名)
例如:
Org.opencv.core.Mat

2.利用JNI编写C++ OpenCV代码,通过Android NDK创建动态库(.so)
然后调用即可

❻ 如何在Android中使用OpenCV

如何在Android程序中使用OpenCV
有两种方式(重点讲后面一种):
1.使用OpenCV Java API。
OpenCV安装路径“F:\OpenCV-2.3.1-android-bin”下有两个文件夹,
将文件夹“OpenCV-2.3.1”拷贝到你的Eclipse工作空间所在的目录,也就是在你的项目的上一级目录中,然后导入到工作空间中,在Package Explorer中选择你的项目,单机右键在弹出菜单中选择Properties,然后在弹出的Properties窗口中左侧选择Android,然后点击右下方的Add按钮,选择OpenCV-2.3.1并点击OK,
此时,展开你的项目树,你可以看到新加了一个OpenCV-2.3.1_src目录,如下图,那么就是正确添加了OpenCV Java API,否则就是你放置OpenCV-2.3.1的目录路径不正确。
然后就可以在你的Java源文件中导入OpenCV的API包,并且使用OpenCV API了,OpenCV API的包的形式如下:
Org.opencv.(OpenCV模块名)。(OpenCV类名)
例如:
Org.opencv.core.Mat
2.利用JNI编写C++ OpenCV代码,通过Android NDK创建动态库(。so)
新建一个工作空间,例如“TestOpenCV”,在Window->Preferences中设置好Android SDK的路径。
然后新建一个Android项目,Build Target选择Android2.2,命名为“HaveImgFun”,活动名改为HaveImgFun,Package name中填写com.testopencv.haveimgfun,最后点击finish。
如同使用OpenCV Java API那样,将OpenCV-2.3.1文件夹拷贝到与工作空间同一级目录中;另外,将“F:\OpenCV-2.3.1-android-bin\samples”下的includeOpenCV.mk文件拷贝到和项目HaveImgFun同一级目录中:
(上面这个各个文件夹和文件的放置很重要,因为OpenCV-2.3.1下的OpenCV.mk中有很多相对路径的指定,如果不是这样放置,在NDK生成动态库时可能会报文件或文件夹无法找到的错误)
选择Package Explorer中你的项目,右键选择new->folder,新建一个名为jni的文件夹,用来存放你的c/c++代码。
然后把res->layout下的main.xml的内容改为下面所示:
1 <?xml version=“1.0” encoding=“utf-8”?> 2 <LinearLayout xmlns:android=“http://schemas.android.com/apk/res/android” 3 android:orientation=“vertical” 4 android:layout_width=“fill_parent” 5 android:layout_height=“fill_parent” 6 > 7 <Button android:layout_height=“wrap_content” 8 android:layout_width=“fill_parent” 9 android:id=“@+id/btnNDK” 10 android:text=“使用C++ OpenCV进行处理” /> 11 <Button android:layout_height=“wrap_content” 12 android:layout_width=“fill_parent” 13 android:id=“@+id/btnRestore” 14 android:text=“还原” /> 15 <ImageView android:id=“@+id/ImageView01” 16 android:layout_width=“fill_parent” 17 android:layout_height=“fill_parent” /> 18 </LinearLayout>
上面的代码就是一个线性布局里面包含2个按钮加上一个显示图像的ImageView
在文件夹src下的com.testopencv.haveimgfun包中新建一个类用于包装使用了opencv c++代码的动态库的导出函数,类名为LibImgFun。
Eclipse会为你创建一个新的文件LibImgFun.java,将里面的内容改为:
1 package com.testopencv.haveimgfun; 2 public class LibImgFun { 3 static { 4 System.loadLibrary(“ImgFun”); 5 } 6 /** 7 * @param width the current view width 8 * @param height the current view height 9 */ 10 public static native int[] ImgFun(int[] buf, int w, int h); 11 }
从上面的代码可以得知,我们的动态库名字应该为“libImgFun.so”,注意“public static native int[] ImgFun(int[] buf, int w, int h)”中的native关键字,表明这个函数来自native code。static表示这是一个静态函数,这样就可以直接用类名去调用。
在jni文件夹下建立一个“ImgFun.cpp”的文件,内容改为下面所示:
1 #include <jni.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <opencv2/opencv.hpp> 5 using namespace cv;6 7 extern “C”8 { 9 JNIEXPORT jintArray JNICALL Java_com_testopencv_haveimgfun_LibImgFun_ImgFun(JNIEnv* env, jobject obj, jintArray buf, int w, int h); 10 JNIEXPORT jintArray JNICALL Java_com_testopencv_haveimgfun_LibImgFun_ImgFun(JNIEnv* env, jobject obj, jintArray buf, int w, int h){ 11 12 jint *cbuf; 13 cbuf = env->GetIntArrayElements(buf, false); 14 if(cbuf == NULL) 15 { 16 return 0; 17 } 18 19 Mat myimg(h, w, CV_8UC4, (unsigned char*)cbuf); 20 for(int j=0;j<myimg.rows/2;j++) 21 { 22 myimg.row(j)。setTo(Scalar(0,0,0,0)); 23 } 24 25 int size=w * h; 26 jintArray result = env->NewIntArray(size); 27 env->SetIntArrayRegion(result, 0, size, cbuf); 28 env->ReleaseIntArrayElements(buf, cbuf, 0); 29 return result; 30 } 31 }
上面的代码中#include <jni.h>是必须要包含的头文件,#include <opencv2/opencv.hpp>是opencv要包含的头文件。
动态库要导出的函数如下声明:
JNIEXPORT jintArray JNICALL Java_com_testopencv_haveimgfun_LibImgFun_ImgFun(JNIEnv* env, jobject obj, jintArray buf, int w, int h);
JNIEXPORT 和JNICALL是必须要加的关键字
jintArray就是int[],这里返回类型要么为空,要么为jni中定义的类型,事实上就是C\C++类型前面加上j,如果是数组,则在后面加上Array。
函数名的命名规则如下:
Java_(包路径)_(类名)_(函数名) (JNIEnv *env, jobject obj, 自己定义的参数…)
包路径中的“.”用“_”(下划线)代替,类名就是上面包装该动态库函数的类的名字,最后一个才是真正的函数名;JNIEnv *env和jobject obj这两个参数时必须的,用来调用JNI环境下的一些函数;后面就是你自己定义的参数。在这里,jintArray buf代表了传进来的图像的数据,int w是图像的宽,int h是图像的高。
这个函数的功能是将传进来的图像的上半部分涂成黑色。
然后再在jni下新建两个文件“Android.mk”文件和“Application.mk”文件,这两个文件事实上就是简单的Makefile文件。
其中将Android.mk的内容改为如下所示:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
include /includeOpenCV.mk
ifeq (“$(wildcard $(OPENCV_MK_PATH))”,“”)
#try to load OpenCV.mk from default install location
include $(TOOLCHAIN_PREBUILT_ROOT)/user/share/OpenCV/OpenCV.mk
else
include $(OPENCV_MK_PATH)
endif
LOCAL_MODULE := ImgFun
LOCAL_SRC_FILES := ImgFun.cpp
include $(BUILD_SHARED_LIBRARY)
Application.mk的内容改为如下所示:
APP_STL:=gnustl_static
APP_CPPFLAGS:=-frtti -fexceptions
APP_ABI:=armeabi armeabi-v7a
其中APP_ABI指定的是目标平台的CPU架构。(经过很多测试,android2.2必须指定为armeabi,android2.2以上的使用armeabi-v7a,如果没有设置对,很有可能安装到android虚拟机失败,当然你同时如上面写上也是可以的)
上面的步骤完成后,就可以使用NDK生成动态库了,打开cygwin,cd到项目目录下:
输入$NDK/ndk-build命令,开始创建动态库。
这时候刷新Eclipse的Package Explorer会出现两个新的文件夹obj和libs。
现在,只剩最后一步完成这个测试程序。
将一张图片,例如“lena.jpg”放到项目res->drawable-hdpi目录中并刷新该目录。
然后将HaveImgFun.java的内容改为下面所示:
1 package com.testopencv.haveimgfun; 2 3 import android.app.Activity; 4 import android.graphics.Bitmap; 5 import android.graphics.Bitmap.Config; 6 import android.graphics.drawable.BitmapDrawable; 7 import android.os.Bundle; 8 import android.widget.Button; 9 import android.view.View; 10 import android.widget.ImageView; 11 12 public class HaveImgFun extends Activity{ 13 /** Called when the activity is first created. */ 14 ImageView imgView; 15 Button btnNDK, btnRestore; 16 17 @Override 18 public void onCreate(Bundle savedInstanceState) { 19 super.onCreate(savedInstanceState); 20 setContentView(R.layout.main); 21 22 this.setTitle(“使用NDK转换灰度图”); 23 btnRestore=(Button)this.findViewById(R.id.btnRestore); 24 btnRestore.setOnClickListener(new ClickEvent()); 25 btnNDK=(Button)this.findViewById(R.id.btnNDK); 26 btnNDK.setOnClickListener(new ClickEvent()); 27 imgView=(ImageView)this.findViewById(R.id.ImageView01); 28 Bitmap img=((BitmapDrawable) getResources()。getDrawable(R.drawable.lena))。getBitmap(); 29 imgView.setImageBitmap(img); 30 } 31 32 class ClickEvent implements View.OnClickListener{ 33 public void onClick(View v){ 34 if(v == btnNDK){35 long current=System.currentTimeMillis(); 36 Bitmap img1=((BitmapDrawable) getResources()。getDrawable(R.drawable.lena))。getBitmap(); 37 int w=img1.getWidth(),h=img1.getHeight(); 38 int[] pix = new int[w * h]; 39 img1.getPixels(pix, 0, w, 0, 0, w, h); 40 int[] resultInt=LibImgFun.ImgFun(pix, w, h); 41 Bitmap resultImg=Bitmap.createBitmap(w, h, Config.RGB_565); 42 resultImg.setPixels(resultInt, 0, w, 0, 0,w, h); 43 long performance=System.currentTimeMillis()-current; 44 imgView.setImageBitmap(resultImg); 45 HaveImgFun.this.setTitle(“w:”+String.valueOf(img1.getWidth())+“,h:”+String.valueOf(img1.getHeight())+“NDK耗时”+String.valueOf(performance)+“ 毫秒”); 46 } else if(v == btnRestore){ 47 Bitmap img2=((BitmapDrawable) getResources()。getDrawable(R.drawable.lena))。getBitmap(); 48 imgView.setImageBitmap(img2); 49 HaveImgFun.this.setTitle(“使用OpenCV进行图像处理”);50 } 51 }52 } 53 }
点击全部保存,OK,现在可以选择一个Android虚拟机运行看一下效果,配置好Run Configuration然后点击Run,得到下面的结果:
点击使用C++ OpenCV进行处理,得到下面的结果:

❼ OpenCV (一)Mat基本操作以及灰度图转化

开始写OpenCV这篇文章的时候,不由想到,我的大学计算机图形学的第一门实操课程就是灰度转化,拉普拉斯锐化等。其中灰度图的转化,是计算机图形学基础中基础,这里就顺着OpenCV的灰度的转化,来看看OpenCV一些基础的api。

本文地址: https://www.jianshu.com/p/7963c7dbaf92

先来看看OpenCV,基础对象Mat,矩阵。什么是矩阵,实际上没有必要解释,一般人都能够明白数学意义上矩阵的含义。

OpenCV把每一个M * N的宽高图像,看成M*N的矩阵。矩阵的每一个单元就对应着图像中像素的每一个点。

我们如果放大图中某个部分,就会发现如下情况

图像实际上就如同矩阵一样每个单元由一个像素点构成。

因为OpenCV的Mat每一个像素点,包含的数据不仅仅只有一个单纯的数字。每一个像素点中包含着颜色通道数据。

稍微解释一下颜色通道,我们可以把世间万物肉眼能识别的颜色由3种颜色(R 红色,G 绿色,B 蓝色)经过调节其色彩饱和度组成的。也就是说通过控制RGB三种的色值大小(0~255)来调配新的颜色。

当我们常见的灰度图,一般是单个颜色通道,因为只用黑白两种颜色。我们常见的图片,至少是三色通道,因为需要RGB三种颜色通道。

我们常见Android的Bitmap能够设置ARGB_8888的标志位就是指能够通过A(透明通道),R,G,B来控制图片加载的颜色通道。

OpenCV为了更好的控制这些数据。因此采用了数学上的矩阵的概念。当OpenCV要控制如RGB三色通道的Mat,本质上是一个M * N * 3的三维矩阵。

但是实际上,我们在使用OpenCV的Mat的时候,我们只需要关注每个图片的像素,而每个像素的颜色通道则是看成Mat中每个单元数据的内容即可

我们先来看看Mat的构造方法

现阶段,实际上我们值得我们注意的是构造函数:

举个例子:

这个mat矩阵将会制造一个高20,宽30,一个1字节的颜色通道(也是Mat中每一个像素数据都是1字节的unchar类型的数据),同时颜色是白色的图片。

在这里面我们能够看到一个特殊的宏CV_8UC1。实际上这是指代OpenCV中图片带的是多少颜色通道的意思。

这4个宏十分重要,要时刻记住。

当我们需要把Mat 中的数据拷贝一份出来,我们应该调用下面这个api:

这样就能拷贝一份像素数据到新的Mat中。之后操作新的Mat就不会影响原图。

实际上,在本文中,我们能够看到OpenCV是这么调用api读取图片的数据转化为Mat矩阵。

OpenCV会通过imread去读图片文件,并且转化为Mat矩阵。

能看见imread,是调用imread_把图片中的数据拷贝的img这个Mat对象中。接着会做一次图片的颠倒。这个方面倒是和Glide很相似。
文件:moles/imgcodecs/src/loadsave.cpp

这里面做了几个事情,实际上和FFmpge的设计十分相似。

其核心也是操作Mat中的像素指针,找到颜色通道,确定指针移动的步长,赋值图片的数据到Mat矩阵中。核心如下:

其中还涉及到jpeg的哈夫曼算法之类的东西,这里就不深入源码。毕竟这是基础学习。

什么是灰度图,灰度度图实际上我们经常见到那些灰白的也可以纳入灰度图的范畴。实际上在计算机图形学有这么一个公式:
将RGB的多颜色图,通过 的算法,将每一个像素的图像的三颜色通道全部转化为为一种色彩,通过上面的公式转为为一种灰色的颜色。

一旦了解了,我们可以尝试编写灰度图的转化。我们通过矩阵的at方法访问每一个像素中的数据。

为了形象表示矩阵指针,指向问题,可以把RGB在OpenCV的Mat看成如下分布:

记住OpenCV的RGB的顺序和Android的不一样,是BGRA的顺序。和我们Android开发颠倒过来。

因此,我们可以得到如下的例子

我们经过尝试之后,确实能够把一个彩色的图片转化一个灰色图片。但是这就是

这里介绍一下Mat的一个api:

实际上OpenCV,内置了一些操作,可以把RGB的图像数据转化灰度图。

我们看看OpenCV实际上的转化出来的灰度图大小。我们通过自己写的方法,转化出来的灰度图是119kb,而通过cvtColor转化出来的是44kb。

问题出在哪里?还记得吗?因为只有灰白两种颜色,实际上只需要一种颜色通道即可,而这边还保留了3个颜色通道,也就说图片的每一个像素点中的数据出现了没必要的冗余。

这样就是44kb的大小。把三颜色通道的数据都设置到单颜色通道之后,就能进一步缩小其大小。

实际上在Android中的ColorMatrix中也有灰度图转化的api。

对画笔矩阵进行一次,矩阵变化操作。

实际上就是做了一次矩阵运算。绘制灰度的时候相当于构建了这么一个矩阵

接着通过矩阵之间的相乘,每一行的 0.213f,0.715f,0.072f控制像素的每个通道的色值。
对于Java来说,灰度转化的算法是: ,把绿色通道的比例调大了。

在OpenCV中有这么两个API,add和addWidget。两者都是可以把图像混合起来。

add和addWidget都是将像素合并起来。但是由于是像素直接相加的,所以容易造成像素接近255,让整个像素泛白。

而权重addWeighted,稍微能减轻一点这种问题,本质上还是像素相加,因此打水印一般不是使用这种办法。
等价于

saturate_cast这个是为了保证计算的值在0~255之间,防止越界。

饱和度,图片中色值更加大,如红色,淡红,鲜红
对比度:是指图像灰度反差。相当于图像中最暗和最亮的对比
亮度:暗亮度

控制对比度,饱和度的公式: , ,

因此当我们想要控制三通道的饱和度时候,可以通过alpha来控制色值成比例增加,beta控制一个色值线性增加。
如下:

在这里,看到了OpenCV会把所有的图片看成Mat矩阵。从本文中,能看到Mat的像素操作可以能看到有两种,一种是ptr像素指针,一种是at。ptr是OpenCV推荐的更加效率的访问速度。

当然还有一种LUT的核心函数,用来极速访问Mat矩阵中的像素。其原理是对着原来的色值进行预先的变换对应(设置一个颜色通道)。用来应对设置阈值等情况。

❽ 安卓opencvmat怎么取值最快

安卓opencvmat取值如下。
1、利用at函数取值,单通道图像读取方式和三通道图像读取方式。
2、使用指针取值。
3、使用迭代器取值。
4、使用矩阵元素的地址定位知识取值。

热点内容
交通银行怎么登陆不了密码 发布:2024-05-17 13:54:48 浏览:543
安卓如何自动连接无线 发布:2024-05-17 13:53:51 浏览:262
python的urlparse 发布:2024-05-17 13:44:20 浏览:769
linux命令全称 发布:2024-05-17 12:07:54 浏览:110
ftpnas区别 发布:2024-05-17 12:06:18 浏览:949
512g存储芯片价格 发布:2024-05-17 12:04:48 浏览:963
脚本运行周期 发布:2024-05-17 11:39:09 浏览:809
阿里云服务器怎么配置发信功能 发布:2024-05-17 11:37:24 浏览:313
编程中的变量 发布:2024-05-17 11:33:06 浏览:777
加密视频怎么解密 发布:2024-05-17 11:02:52 浏览:572