DSP

opencv4android--RGB2HSV

2019-07-13 18:50发布

opencv4android–RGB2HSV

最近上班,工作强度不大,自己就找点东西学,正好碰见之前一个朋友面试,面试官出了一个题,自己闲着无聊也就研究研究,学习些新的东西。,先看一下题目。 题目中关键点估计就是opencv的hsv转换,说实话我当是也不知道那是什么东西,百度稍微了解下大致有了个思路。
  1. 调用相机拍照
  2. 将拍好的照片截图
  3. 配置opencv使用环境
  4. 调用opencv的方法
总体说来应该就这四步,前两步不难虽然我不会写,但是会百度啊,使用opencv就得自己研究了!

拍照加截图

百度了一圈,试了好几种方案,只有这个成功了,就用这个吧!思路是先调用相机,拍照返回后调用系统自带的截图,确定大小之后返回确定之后的uri。具体代码如下:
初始化一些常量 String path = getSDCardPath(); File file = new File(path + "/temp.jpg"); imageUri = Uri.fromFile(file); File cropFile = new File(getSDCardPath() + "/temp_crop.jpg"); imageCropUri = Uri.fromFile(cropFile); getSDcardPath方法 public static String getSDCardPath() { String cmd = "cat /proc/mounts"; Runtime run = Runtime.getRuntime(); try { Process p = run.exec(cmd); BufferedInputStream in = new BufferedInputStream(p.getInputStream()); BufferedReader inBr = new BufferedReader(new InputStreamReader(in)); String lineStr; while ((lineStr = inBr.readLine()) != null) { if (lineStr.contains("sdcard") && lineStr.contains(".android_secure")) { String[] strArray = lineStr.split(" "); if (strArray != null && strArray.length >= 5) { String result = strArray[1].replace("/.android_secure", ""); return result; } } if (p.waitFor() != 0 && p.exitValue() == 1) { } } inBr.close(); in.close(); } catch (Exception e) { return Environment.getExternalStorageDirectory().getPath(); } return Environment.getExternalStorageDirectory().getPath(); } 启动相机 Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);//action is capture intent.putExtra("return-data", false); intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri); intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString()); intent.putExtra("noFaceDetection", true); startActivityForResult(intent, RESULT_CAMERA_ONLY); 启动截图 private void cropImg(Uri imageUri) { Intent intent = new Intent("com.android.camera.action.CROP"); intent.setDataAndType(imageUri, "image/*"); intent.putExtra("crop", "true"); intent.putExtra("aspectX", 1); intent.putExtra("aspectY", 1); intent.putExtra("outputX", 700); intent.putExtra("outputY", 700); intent.putExtra("return-data", false); intent.putExtra(MediaStore.EXTRA_OUTPUT, imageCropUri); intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString()); intent.putExtra("noFaceDetection", true); startActivityForResult(intent, RESULT_CAMERA_CROP_PATH_RESULT); } onActivityResult回调 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); Log.d("TAG","onActivityResult"); if(resultCode!=RESULT_OK){ Toast.makeText(MainActivity.this,"ActivityResult resultCode error",Toast.LENGTH_SHORT).show(); return; } switch (requestCode) { case RESULT_CAMERA_ONLY://拍照成功回调 cropImg(imageUri); break; case RESULT_CAMERA_CROP_PATH_RESULT://截图成功回调 Bundle extras = data.getExtras(); if (extras != null) { try { mBitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageCropUri)); mImage.setImageBitmap(mBitmap); } catch (Exception e) { e.printStackTrace(); } } } } 主要的就是上面这些代码,先调用相机之后返回调用截图之后在返回,imageview加载由本地url生成的bitmap图像,这样钱两步就完成了。

配置opencv环境

opencv下载地址:https://pan.baidu.com/s/1geNBqSV
本来是csdn的不过有点大就上传不了,目前版本是3.1,最新的。 不懂是什么东西的可以去百度。当然我百度完了也不明白是什么东西,大概了解是做图像处理的,反正特别XX就是了,先说一下集成环境,网上有很多方案不过都是很久以前的了,参考很多资料之后决定用这位大神的,简单明了。步步到位。http://www.cnblogs.com/tail/p/4618476.html
最后一步测试成功什么的就不用了,咱们直接继续。

简单使用

网上很多都说需要什么NDK调用,也不会啊,不过上面的大神提到了在opencv3.0之后就可以非常简单的使用了,可以去参考sample中第一个例子。代码 @Override protected 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); } } } 复制粘贴之后会发现mLoaderCallback报错,因为没有嘛,还需要创建一个成员变量。 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 */ } break; default: { super.onManagerConnected(status); } break; } } }; 运行的时候要是成功打印log了,说明之前的配置都是没有问题的。
接下来就是简单实用,因为要将RGB转化为HSV,简单百度下,没找到完成的例子,发现一个改变图片灰度的例子,于是尝试了一下。说一下具体步骤:
  1. 创建两个bitmap,一个用来保存变化之前的图像,一个用来保存变化之后的图像
  2. 创建两个图像对应的矩阵
  3. 使用opencv方法变成灰度图
  4. imageview显示 Mat rgbMat=new Mat();//rgb矩阵 Mat grayMat=new Mat();//gray矩阵 //灰度之后的Bitmap,mBitmap为RgbBitmap,之前已经赋过值了。 grayBitmap=Bitmap.createBitmap(mBitmap.getWidth(),mBitmap.getHeight(), Bitmap.Config.RGB_565); Utils.bitmapToMat(mBitmap,rgbMat);//将图像转换为矩阵 Imgproc.cvtColor(rgbMat,grayMat,Imgproc.COLOR_RGB2GRAY);//矩阵变化 Utils.matToBitmap(grayMat,grayBitmap);//将矩阵转化为图像 mImage.setImageBitmap(grayBitmap);//显示图像 在敲的过程中可以发现,在矩阵变化的时候有很多种变化的方式,由于要使用RGB2HSV,正好也有这种模式就把COLOR_RGB2GRAY变成COLOR_RGB2HSV,也不知道这么写对不对,反正是有变化,已经让朋友给那个面试的人看了效果,准备再深入研究研究opencv,确实很强大啊!效果图:
可能有点卡,将就吧,等面试的那个人看看是不是想要的效果。