当前位置: 首页 > news >正文

可以进入的网站建设储蓄卡网站

可以进入的网站,建设储蓄卡网站,苏州建设网站找网络公司,4500双休一天8小时1. 前言 最近在使用OpenCV处理图片的时候#xff0c;经常会遇到需要转换图像的情况#xff0c;网上相关资料比较少#xff0c;也不全#xff0c;有时候得费劲老半天才能搞定。 自己踩了坑后#xff0c;在这里记录下#xff0c;都是我在项目中遇到的图像转化操作#xf…1. 前言 最近在使用OpenCV处理图片的时候经常会遇到需要转换图像的情况网上相关资料比较少也不全有时候得费劲老半天才能搞定。 自己踩了坑后在这里记录下都是我在项目中遇到的图像转化操作是一些常用的图像格式转换操作。 具体包括: nv21、rgba、rgb转换OpenCV的Mat转为BitmapBitmap转成RGB888NV21转成BitmapCamera2 中的 android.media.Image 转为 NV21Android传递Bitmap给JNI并转为rgba的MatJPEG 转 NV21 本文的操作都是基于Activity横屏的情况下进行的 2. nv21、rgba、rgb转换 nv21是YUV420格式中的一种在Android中Camera1获取的摄像头数据就是NV21格式的。 rgba、rgb格式是不同于YUV的另一种色彩表示方式通常我们需要转为RGB格式再去做图像检测和处理。 所以在Android中nv21和rgb的转换是比较常用、比较普遍的。 2.1 nv21转为rgba格式的Mat 这里传入的jbyteArray data_是nv21格式首先转成nv21的Mat然后在通过cv::cvtColor方法通过cv::COLOR_YUV2RGBA_NV21这个参数值转为rgba格式的Mat。 extern C JNIEXPORT jbyteArray JNICALL Java_com_heiko_myncnnlib_NcnnNativeLib_nv21toARGB(JNIEnv *env, jobject thiz, jbyteArray data_,jint h, jint w) {jbyte *data env-GetByteArrayElements(data_, NULL);cv::Mat nv21(h h / 2, w, CV_8UC1, data);cv::Mat rgba(h, w, CV_8UC4);//nv21转为rgba格式cv::cvtColor(nv21, rgba, cv::COLOR_YUV2RGBA_NV21);//省略了后续无关代码....//释放资源env-ReleaseByteArrayElements(data_, data, 0); }2.2 nv21转为rgb的Mat 将nv21转成rgb格式的Mat这里的COLOR_YUV420sp2RGB和COLOR_YUV2RGB_NV21是一样的。 cv::Mat rgba(h, w, CV_8UC3); //将nv21的数据转为RGB cv::cvtColor(nv21, rgb, cv::COLOR_YUV420sp2RGB); //也可以传COLOR_YUV2RGB_NV212.3 rgba转为rgb的Mat cv::Mat rgb(rows, cols, CV_8UC3); //将rgba转为rgb cv::cvtColor(rgba, rgb, CV_RGBA2RGB);3. OpenCV的Mat转为Bitmap 在JNI中用OpenCV处理好图像后得到的结果是Mat那么需要将其转为byteArray然后传递到Android层再转为Bitmap显示到ImageView上。 3.1 RGBA转成Bitmap 转成RGBA相对比较简单只要将rgba的Mat转为jbyteArray传递到Android层就好。 extern C JNIEXPORT jbyteArray JNICALL Java_com_heiko_myncnnlib_NcnnNativeLib_nv21toARGB(JNIEnv *env, jobject thiz, jbyteArray data_,jint h, jint w) {jbyte *data env-GetByteArrayElements(data_, NULL);cv::Mat nv21(h h / 2, w, CV_8UC1, data);cv::Mat rgba(h, w, CV_8UC4);cv::cvtColor(nv21, rgba, cv::COLOR_YUV2RGBA_NV21);int rows h;int cols w;jbyteArray byteArray env-NewByteArray(rows * cols * 4);env-SetByteArrayRegion(byteArray, 0, rows * cols * 4, reinterpret_castjbyte*(rgba.data));env-ReleaseByteArrayElements(data_, data, 0);return byteArray; }Android层进行调用这里创建Bitmap的时候使用的是Bitmap.Config.ARGB_8888 //由于前摄像头放置位置是90度方向的所以这里height和width对调 (实际上应该是在JNI里进行旋转操作这里是怎么方便怎么来)var result nativeLib.nv21toARGB(data,height,width)//var result nativeLib.nv21toARGB(data,width,height)//byte数组转为ARGB8888的Bitmapval bitmap Bitmap.createBitmap(width,height,Bitmap.Config.ARGB_8888)var buffer ByteBuffer.wrap(result)bitmap.copyPixelsFromBuffer(buffer) runOnUiThread {//显示到Bitmap上binding.img1.setImageBitmap(bitmap) }3.2 RGB888转RGB565后再转成Bitmap 先来看一下RGB888转RGB565的方法 uint16_t *rgb888toRgb565(cv::Mat rgb, int rows, int cols) {cv::Vec3b *data rgb.ptrcv::Vec3b(0);uint16_t *rgb565 new uint16_t[rows * cols];for (int i 0; i rows * cols; i) {int r data[i][0];int g data[i][1];int b data[i][2];rgb565[i] ((r 3) 11) | ((g 2) 5) | (b 3);}return rgb565; }实现JNI方法这里传入的data_是rgb888格式然后转成Mat再调用rgb888toRgb565转成rgb565最后在转成jbyteArray返回给Android层。 extern C JNIEXPORT jbyteArray JNICALL Java_com_heiko_MyTest_rgb888ToRgb565(JNIEnv *env, jobject thiz, jbyteArray data_,jint w, jint h) {jbyte *data env-GetByteArrayElements(data_, NULL);unsigned char *rgb_data reinterpret_castunsigned char *(data);cv::Mat rgb(h, w, CV_8UC3, rgb_data);int rows h;int cols w;jbyteArray byteArray env-NewByteArray(rows * cols * 2);uint16_t *rgb565 rgb888toRgb565(rgb, rows, cols);env-SetByteArrayRegion(byteArray, 0, rows * cols * 2, reinterpret_castjbyte *(rgb565));env-ReleaseByteArrayElements(data_, data, 0);return byteArray; }Android层进行调用这里创建Bitmap的时候使用的是Bitmap.Config.RGB_565 //这里的data是RGB888格式具体看4.x小节 val result : ByteArray nativeLib.rgb888ToRgb565(data, imageWidth, imageHeight) //byte数组转为Bitmap val bitmap Bitmap.createBitmap(imageWidth, imageHeight, Bitmap.Config.RGB_565) var buffer ByteBuffer.wrap(detectResult) bitmap.copyPixelsFromBuffer(buffer)runOnUiThread { //显示到ImageView上binding.img1.setImageBitmap(bitmap) }3.3 RGBA转RGB565 rgba也可以先转成rgb565后再传递给Android层代码如下 uint16_t *rgbaToRgb565(cv::Mat rgb, int rows, int cols) {cv::Vec4b *data rgb.ptrcv::Vec4b(0);uint16_t *rgb565 new uint16_t[rows * cols];for (int i 0; i rows * cols; i) {int r data[i][0];int g data[i][1];int b data[i][2];rgb565[i] ((r 3) 11) | ((g 2) 5) | (b 3);}return rgb565; }4. Bitmap转RGB888 Android中的Bitmap是ARGB格式进行存储的所以我们先取到Bitmap的像素数组然后对其进行遍历分别取到每个像素点的R、G、B数据赋值到新的ByteArray里就得到RGB888格式的图像数据了。 //解析bytes为bitmapbytes是jpeg格式的图片流 val bitmap BitmapFactory.decodeByteArray(bytes, 0, bytes.size) val width: Int bitmap.width val height: Int bitmap.height val pixels IntArray(width * height) //获取像素赋值给 pixels bitmap.getPixels(pixels, 0, width, 0, 0, width, height)val rgb888 ByteArray(width * height * 3) for (i in 0 until width * height) {// 注意Android的Bitmap是ARGB格式而不是RGBArgb888[i * 3] Color.red(pixels[i]).toByte()rgb888[i * 3 1] Color.green(pixels[i]).toByte()rgb888[i * 3 2] Color.blue(pixels[i]).toByte() }5. YUV420转Bitmap 这里的yuv420的具体格式是NV21也就是将NV21格式转为Bitamp。 具体操作为先将nv21的ByteArray转化为YuvImage对象然后压缩为JPEG格式的ByteArray最后通过BitmapFactory.decodeByteArray()来得到Bitmap。 fun convertYUV420ToBitmap(yuv420Data: ByteArray?,width: Int,height: Int): Bitmap {// 创建YuvImage对象val yuvImage YuvImage(yuv420Data, ImageFormat.NV21, width, height, null)// 创建ByteArrayOutputStream对象val outputStream ByteArrayOutputStream()// 将YuvImage对象压缩为JPEG格式的数据yuvImage.compressToJpeg(Rect(0, 0, width, height), 100, outputStream)// 将JPEG数据解码为Bitmap对象val jpegData outputStream.toByteArray()return BitmapFactory.decodeByteArray(jpegData, 0, jpegData.size) }6. android.media.Image 转为 NV21 Android Camera2相机中取到的一帧数据是android.media.Image我们设置android.graphics.ImageFormat为ImageFormat.YUV_420_888这个格式是YCbCr的泛化格式不会具体指明是YU12YV12NV12或是是NV21。它能够表示任何4:2:0的平面和半平面格式每个分量用8 bits表示。 这里我们来将Image转为NV21格式。 fun imageToNV21(image: Image): ByteArray {val planes: ArrayImage.Plane image.planesval yBuffer planes[0].bufferval uBuffer planes[1].bufferval vBuffer planes[2].bufferval ySize yBuffer.remaining()val uSize uBuffer.remaining()val vSize vBuffer.remaining()val yuvData ByteArray(ySize uSize vSize)yBuffer[yuvData, 0, ySize]vBuffer[yuvData, ySize, vSize]uBuffer[yuvData, ySize vSize, uSize]return yuvData }7. Android传递Bitmap给JNI并转为rgba的Mat Android中也可以直接向JNI传递Bitmap对象然后在JNI中再去对Bitmap进行操作。 extern C JNIEXPORT jbyteArray JNICALL Java_com_zeekr_ncnnlib_NcnnNativeLib_humanDetectBitmap(JNIEnv *env, jobject thiz, jobject bitmap) {AndroidBitmapInfo bitmapInfo;//获取Bitmap的信息AndroidBitmap_getInfo(env, bitmap, bitmapInfo);int rows bitmapInfo.height;int cols bitmapInfo.width;void *bitmapPixels;//获取Bitmap的像素AndroidBitmap_lockPixels(env, bitmap, bitmapPixels);//转成rgba的Matcv::Mat rgba(rows, cols, CV_8UC4, bitmapPixels);AndroidBitmap_unlockPixels(env, bitmap);//省略了后续无关代码 }关于在JNI中创建Bitmap并传递到Android层具体可以看我的这篇文章 : Android JNI/NDK 入门从一到二_氦客的博客-CSDN博客 8. JPEG转NV21 传入jpeg格式的ByteArray返回NV21格式的ByteArray fun jpegToNV21(jpegData: ByteArray, width: Int, height: Int): ByteArray {val bitmap BitmapFactory.decodeByteArray(jpegData, 0, jpegData.size)val argb IntArray(width * height)bitmap.getPixels(argb, 0, width, 0, 0, width, height)val yuv ByteArray(width * height * 3 / 2)encodeYUV420SP(yuv, argb, width, height)bitmap.recycle()return yuv }private fun encodeYUV420SP(yuv420sp: ByteArray, argb: IntArray, width: Int, height: Int) {val frameSize width * heightvar yIndex 0var uvIndex frameSize//var a: Intvar R: Intvar G: Intvar B: Intvar Y: Intvar U: Intvar V: Intfor (j in 0 until height) {for (i in 0 until width) {//a argb[j * width i] and -0x1000000 shr 24R argb[j * width i] and 0xff0000 shr 16G argb[j * width i] and 0xff00 shr 8B argb[j * width i] and 0xff shr 0Y (66 * R 129 * G 25 * B 128 shr 8) 16U (-38 * R - 74 * G 112 * B 128 shr 8) 128V (112 * R - 94 * G - 18 * B 128 shr 8) 128yuv420sp[yIndex] (if (Y 0) 0 else if (Y 255) 255 else Y).toByte()if (j % 2 0 i % 2 0) {yuv420sp[uvIndex] (if (V 0) 0 else if (V 255) 255 else V).toByte()yuv420sp[uvIndex] (if (U 0) 0 else if (U 255) 255 else U).toByte()}}} }本文为氦客在CSDN上独家发布 : https://blog.csdn.net/EthanCo
http://www.eeditor.cn/news/120028/

相关文章:

  • 网站后台首页设计php网站建设与维护
  • 项城市建设方案公示在哪个网站专业设计美容院装修公司
  • 怎么建设网站后台企业网站做凭安认证有用吗
  • 精品网站建设多少钱公司培训网站需要广播证吗
  • 营口网站建设开发制作最新军事新闻12小时
  • 网站添加悬浮二维码品牌网站解决方案
  • 易语言 网站开发推广普通话手抄报简单又好看
  • 苏州企业建站公司wordpress添加悬浮按钮
  • 回龙观做网站网络营销的内容主要包括哪些方面
  • 关于销售网站有哪些内容asp企业网站开发技术
  • 免费网站模板大全网站建设能力
  • 秦皇岛做网站的公司百度浏览器广告怎么投放
  • 厦门专业网站设计微信公众平台网页
  • 建设企业学习网站pc网站建设的优势是什么
  • 注册公司去哪个网站做网站编辑的时候没保存怎么
  • 网站建设培训资料江门公司做网站
  • 企业网站维护建设ppt东莞外发加工货源网
  • 越南的网站建设传奇手游源码网
  • 伍佰亿营销型网站注册的空间网站吗
  • 长春网站开发招聘网站的策划做推广
  • 怎么做提卡密网站苏州做手机网站
  • 衡阳建网站技术支持 鼎维重庆网站建设专家
  • 微网站二级页面怎么做洛阳做网站公司汉狮价格
  • 个人博客网站建设业务网站设计 cdc
  • 龙岗做网站公司苏州网络营销网站建设平台
  • 北京网站优化服务有限公司织梦批量修改网站源代码
  • 智能建站系统怎么更换网站模板创新的企业网站开发
  • 请人做游戏的网站英文官网建设
  • 浙江省建设局网站wordpress双击图片放大
  • 临沂网站优化互联网营销师报名入口官网