草庐IT

Android App开发超实用实例 | OpenCV在Android手机实现在图像上添加文本

TiAmo zhang 2023-04-15 原文

 OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉库,它可以运行在Linux、Windows、Android和Mac OS等操作系统上。OpenCV原本由一系列 C 函数和少量 C++ 类构成,同时提供了Python等其他语言的接口,它实现了图像处理和计算机视觉方面的很多通用算法。下面这个实例演示了使用OpenCV在Android手机实现在图像上绘制文本。本文提供的OpenCV实例使用Java语言编写,并且运行在Android手机上。

01、实例功能

此实例主要通过使用Imgproc的putText()方法,实现在图像上绘制(添加)文本。Imgproc是Image和Processing这两个单词的缩写组合,它是OpenCV的图像处理模块,该模块包含如下内容:线性和非线性的图像滤波、图像的几何变换、图像转换、直方图相关、结构分析和形状描述、运动分析和对象跟踪、特征检测、目标检测等。

当实例运行之后,单击“显示原始图像”按钮,原始图像的效果如图1(a)所示。单击“在图像上添加文本”按钮,在图像上添加文本(OpenCV)之后的效果如图1(b)所示。

 

02、实现代码

public class MainActivity extends Activity {
 ImageView myImageView;
 Bitmap myBitmap;
 static{ System.loadLibrary("opencv_java3");}               //加载OpenCV库
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  myImageView = (ImageView) findViewById(R.id.myImageView);
  myBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.myimage1);
 }
 public void onClickButton1(View v) {       //响应单击按钮“显示原始图像”
  myImageView.setImageBitmap(myBitmap);
 }
 public void onClickButton2(View v) {     //响应单击按钮“在图像上添加文本”
  Bitmap myNewBitmap=Bitmap.createBitmap(myBitmap.getWidth(),
          myBitmap.getHeight(),Bitmap.Config.RGB_565); //根据原始图像创建空Bitmap
  Mat myMat=new Mat();
  Utils.bitmapToMat(myBitmap,myMat);                //将原始图像保存至myMat
  Point myPoint=new Point(300, 700);                //定义绘制文本的起始位置
  Scalar myScalar=new Scalar(255,0,0,255);              //设置绘制文本的颜色
  //在图像上添加文本(仅支持英文、符号等,中文暂不支持)
  Imgproc.putText(myMat,"OpenCV",myPoint,
          Core.FONT_HERSHEY_COMPLEX,4,myScalar,3);
  //将添加文本之后的图像输出至myNewBitmap
  Utils.matToBitmap(myMat,myNewBitmap);
  //通过ImageView控件显示叠加文本之后的图像
  myImageView.setImageBitmap(myNewBitmap);
 }
}

03、代码说明

上面这段代码在MyCode\MySampleK31\app\src\main\java\com\bin\luo\mysample\ MainActivity.java文件中。在这段代码中,Imgproc的putText()方法用于在图像上添加文字(字母),该方法的语法声明如下:

其中,参数Mat img表示待绘制的图像;参数String text表示待绘制的文字;参数Point org表示文字的起点坐标;参数int fontFace表示字体;参数double fontScale表示文字大小因子,值越大文字越大;参数Scalar color表示文字颜色;参数int thickness表示文字线条宽度。

Utils.bitmapToMat(myBitmap,myMat)用于将Bitmap输出到Mat,该方法的语法声明如下: 

其中,参数Bitmap bmp表示源Bitmap,支持ARGB_8888和RGB_565像素类型;参数Mat mat表示目标Mat,默认类型是CV_8UC4类型,大小和Bitmap一样,通道顺序为RGBA。

Utils.matToBitmap(myMat,myNewBitmap)用于将Mat输出到Bitmap,该方法的语法声明如下: 

其中,参数Mat mat表示源Mat,支持CV_8UC1,CV_8UC3或CV_8UC4类型;参数Bitmap bmp表示目标Bitmap,支持ARGB_8888或RGB_565类型。

static{ System.loadLibrary("opencv_java3");}表示加载OpenCV库。默认情况下,在Android中使用OpenCV需要导入相关的库文件,具体操作步骤如下。 

(1) 从https://opencv.org/releases.html页面中单击Android pack超链接,稍等一会儿即可弹出“新建下载任务”对话框,然后在该对话框中单击“下载”按钮,执行下载操作,如图2所示。在下载完成之后解压文件即可。在此实例中,可以忽略此步骤,直接从源代码中复制openCVLibrary345Copy文件夹到项目即可。

 

(2) 在Android Studio菜单上依次选择File\New\Import Module...,弹出Import Module from Source对话框。在该对话框中单击“Source directory:”右端的文件夹按钮,然后选择openCVLibrary345Copy文件夹,会出现错误(重复)提示。直接在“Module name:”输入框中将openCVLibrary345Copy修改为openCVLibrary345,错误提示消失,如图3所示。再单击Finish按钮即可。

 (3) 按照如下粗体字所示修改MyCode\MySampleK31\app\build.gradle文件。完成之后同步(Sync Now)即可。

apply plugin: 'com.android.application'
android {
    compileSdkVersion 29
    buildToolsVersion "29.0.2"
    defaultConfig {
        applicationId "com.bin.luo.mysample"
        minSdkVersion 27
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    sourceSets {  main { jniLibs.srcDirs = ['libs'] } }
}
dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'androidx.appcompat:appcompat:1.0.2'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    testImplementation 'junit:junit:4.12'
    implementation project(':openCVLibrary345')
    androidTestImplementation 'androidx.test:runner:1.2.0'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}

 (4) 复制MyCode\MySampleK31\app\libs文件夹下的所有内容到(用户的)项目中即可。该文件夹及其子文件夹的文件与手机CPU的类型有关,缺少这些文件在编译或运行时会报错或无响应。

特别说明 /

在测试前必须从MyCode\MySampleK31\app\libs文件夹复制该文件夹中的所有子文件夹及其文件到(用户的)项目的libs文件夹。

04、补充说明

在测试代码时,必须保持网络畅通。

有关Android App开发超实用实例 | OpenCV在Android手机实现在图像上添加文本的更多相关文章

  1. ruby - 在 Ruby 中编写命令行实用程序 - 2

    我想用ruby​​编写一个小的命令行实用程序并将其作为gem分发。我知道安装后,Guard、Sass和Thor等某些gem可以从命令行自行运行。为了让gem像二进制文件一样可用,我需要在我的gemspec中指定什么。 最佳答案 Gem::Specification.newdo|s|...s.executable='name_of_executable'...endhttp://docs.rubygems.org/read/chapter/20 关于ruby-在Ruby中编写命令行实用程序

  2. ruby - 使用 C 扩展开发 ruby​​gem 时,如何使用 Rspec 在本地进行测试? - 2

    我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当

  3. ruby-on-rails - 如何使用 instance_variable_set 正确设置实例变量? - 2

    我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击

  4. ruby 正则表达式 - 如何替换字符串中匹配项的第 n 个实例 - 2

    在我的应用程序中,我需要能够找到所有数字子字符串,然后扫描每个子字符串,找到第一个匹配范围(例如5到15之间)的子字符串,并将该实例替换为另一个字符串“X”。我的测试字符串s="1foo100bar10gee1"我的初始模式是1个或多个数字的任何字符串,例如,re=Regexp.new(/\d+/)matches=s.scan(re)给出["1","100","10","1"]如果我想用“X”替换第N个匹配项,并且只替换第N个匹配项,我该怎么做?例如,如果我想替换第三个匹配项“10”(匹配项[2]),我不能只说s[matches[2]]="X"因为它做了两次替换“1fooX0barXg

  5. Ruby Sinatra 配置用于生产和开发 - 2

    我已经在Sinatra上创建了应用程序,它代表了一个简单的API。我想在生产和开发上进行部署。我想在部署时选择,是开发还是生产,一些方法的逻辑应该改变,这取决于部署类型。是否有任何想法,如何完成以及解决此问题的一些示例。例子:我有代码get'/api/test'doreturn"Itisdev"end但是在部署到生产环境之后我想在运行/api/test之后看到ItisPROD如何实现? 最佳答案 根据SinatraDocumentation:EnvironmentscanbesetthroughtheRACK_ENVenvironm

  6. ruby-on-rails - Rails - 从另一个模型中创建一个模型的实例 - 2

    我有一个正在构建的应用程序,我需要一个模型来创建另一个模型的实例。我希望每辆车都有4个轮胎。汽车模型classCar轮胎模型classTire但是,在make_tires内部有一个错误,如果我为Tire尝试它,则没有用于创建或新建的activerecord方法。当我检查轮胎时,它没有这些方法。我该如何补救?错误是这样的:未定义的方法'create'forActiveRecord::AttributeMethods::Serialization::Tire::Module我测试了两个环境:测试和开发,它们都因相同的错误而失败。 最佳答案

  7. ruby-on-rails - RSpec:避免使用允许接收的任何实例 - 2

    我正在处理旧代码的一部分。beforedoallow_any_instance_of(SportRateManager).toreceive(:create).and_return(true)endRubocop错误如下:Avoidstubbingusing'allow_any_instance_of'我读到了RuboCop::RSpec:AnyInstance我试着像下面那样改变它。由此beforedoallow_any_instance_of(SportRateManager).toreceive(:create).and_return(true)end对此:let(:sport_

  8. ruby - 是否可以覆盖 gemfile 进行本地开发? - 2

    我们的git存储库中目前有一个Gemfile。但是,有一个gem我只在我的环境中本地使用(我的团队不使用它)。为了使用它,我必须将它添加到我们的Gemfile中,但每次我checkout到我们的master/dev主分支时,由于与跟踪的gemfile冲突,我必须删除它。我想要的是类似Gemfile.local的东西,它将继承从Gemfile导入的gems,但也允许在那里导入新的gems以供使用只有我的机器。此文件将在.gitignore中被忽略。这可能吗? 最佳答案 设置BUNDLE_GEMFILE环境变量:BUNDLE_GEMFI

  9. ruby - 在 Windows 机器上使用 Ruby 进行开发是否会适得其反? - 2

    这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby​​-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub

  10. ruby-on-rails - 在 Rails 开发环境中为 .ogv 文件设置 Mime 类型 - 2

    我正在玩HTML5视频并且在ERB中有以下片段:mp4视频从在我的开发环境中运行的服务器很好地流式传输到chrome。然而firefox显示带有海报图像的视频播放器,但带有一个大X。问题似乎是mongrel不确定ogv扩展的mime类型,并且只返回text/plain,如curl所示:$curl-Ihttp://0.0.0.0:3000/pr6.ogvHTTP/1.1200OKConnection:closeDate:Mon,19Apr201012:33:50GMTLast-Modified:Sun,18Apr201012:46:07GMTContent-Type:text/plain

随机推荐