最近项目中需要做到图片相似度对比,搜了半天,网上有很多直接方法,但是感觉没那么靠谱,都是有弊端,eg:/hnulwt/article/details/43668161
/u010652002/article/details/72722198
上面的方法都很有价值。
觉的最靠谱的方法有两种:
一种是使用tess-two,训练自己的图片,然后做识别,但是中间遇到了写问题就没有用。
有想试试的可以访问/u013087553/article/details/94445109
另一种是使用openCV,里面有pareHist这个方法可以比较图片相似度,倒是很方便。
下面我就讲讲关于使用openCV的坑(找了半天文章,各种问题出现):
一、集成OpenCV
1.到openCV官网下载android版,我下的是最新的4.1.1。
下载完后有四个文件:
2.
导入java文件;进入file-new-import module,source directory中填入之前介绍的sdk包中的java文件,如下图所示,填好之后,会自动填入java(可以自己改名字),(如下图所示)然后点击next。
然后出现下图,直接点击finish:
然后opencv就被导入项目了,样子如下图。
然后咱们引用一下File --- Project Structure ---- app ----Dependencies,点击“+”号,选择第三个module dependcy,把java引入:
但是会报错,别着急,一项一项解决:
1.将java的build.gradle打开,修改compileSdkVersion和buildToolsVersion改成跟app里面的一致。
2.将apply plugin: 'com.android.application' 改为apply plugin: 'com.android.library'。
3.将defaultConfig删除。
4.将app的build.gradle中applicationId这句话也删掉。
现在就不会报错了。
3.在app/src/main目录下新建个jinLibs的文件夹,将sdk下native下的libs复制进来:
到这我以为可以使用了,在mainActivity初始化一下:
@Overrideprotected void onResume() {super.onResume();if(!OpenCVLoader.initDebug()){Log.d(getClass().getName(),"Internal OpenCV library not found. Using OpenCV manger for initialization");OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_0_0, this, mLoaderCallback);}else{Log.d(getClass().getName(),"OpenCV library found inside package. Using it!");mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);}}private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {@Overridepublic void onManagerConnected(int status) {switch (status) {case LoaderCallbackInterface.SUCCESS: {Log.i("rr", "OpenCV loaded successfully");}break;default: {super.onManagerConnected(status);}break;}}};
然后运行一下,网上都是说这样就不需要安装manager,但是我运行以后还是让安装:
我看了一下日志,如下:
上面显示"info"和"libc++"没有找到,点进去我看了一下,"info"不需要管,它里面try,catch了。我们需要解决一下"lib++"这个问题,我试了半天都没用,在defaultConfig添加了 ndk {//设置支持的SO库架构abiFilters 'x86', 'armeabi-v7a', 'x86_64', 'arm64-v8a'}这句话也没用,我就去掉了,但是从别人的项目拷了so文件就好了,如果你也不行到时候从我项目拷so文件就行。
因为我要做的是图片相似度对比,接下来的就是图片相似度对比的代码:
主要代码:
@Overridepublic void onClick(View v) {Mat mat1 = new Mat();Mat mat2 = new Mat();Mat mat11 = new Mat();Mat mat22 = new Mat();Utils.bitmapToMat(mBitmap1, mat1);Utils.bitmapToMat(mBitmap2, mat2);Imgproc.cvtColor(mat1, mat11, Imgproc.COLOR_BGR2GRAY);Imgproc.cvtColor(mat2, mat22, Imgproc.COLOR_BGR2GRAY);comPareHist(mat11, mat22);}/*** 比较来个矩阵的相似度* @param srcMat* @param desMat*/public void comPareHist(Mat srcMat,Mat desMat){srcMat.convertTo(srcMat, CvType.CV_32F);desMat.convertTo(desMat, CvType.CV_32F);double target = pareHist(srcMat, desMat, Imgproc.CV_COMP_CORREL);Log.e(TAG, "相似度 : ==" + target);Toast.makeText(this, "相似度 : ==" + target, Toast.LENGTH_SHORT).show();}
这里需要注意的一点,两张图片的尺寸一定要一样,不然会报:Error: Assertion failed (A.size == arrays[i0]->size) in init, file /build/master_pack-android/opencv/modules/core/src/matrix_iterator.cpp, line 72这个错。
项目地址:
链接:/s/1R1bJdPmqJkPue5pgryGAEw
提取码:us1f
如果觉得《android 使用opencv4 图片相似度对比》对你有帮助,请点赞、收藏,并留下你的观点哦!