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

网站更新了域名如何找到东莞城乡住房建设厅网站

网站更新了域名如何找到,东莞城乡住房建设厅网站,网络营销推广渠道有哪些,做网站的公司名字概述 在 Android 中#xff0c;要比对两张 Bitmap 图片的相似度#xff0c;常见的方法有基于像素差异、直方图比较、或者使用一些更高级的算法如 SSIM#xff08;结构相似性#xff09;和感知哈希#xff08;pHash#xff09;。 1. 基于像素的差异比较 可以逐像素比较…概述 在 Android 中要比对两张 Bitmap 图片的相似度常见的方法有基于像素差异、直方图比较、或者使用一些更高级的算法如 SSIM结构相似性和感知哈希pHash。 1. 基于像素的差异比较 可以逐像素比较两张 Bitmap计算它们之间的差异。以下是一个简单的逐像素比较的例子 public static double compareBitmaps(Bitmap bitmap1, Bitmap bitmap2) {if (bitmap1.getWidth() ! bitmap2.getWidth() || bitmap1.getHeight() ! bitmap2.getHeight()) {throw new IllegalArgumentException(Bitmap sizes are different!);}int width bitmap1.getWidth();int height bitmap1.getHeight();long diff 0;for (int y 0; y height; y) {for (int x 0; x width; x) {int pixel1 bitmap1.getPixel(x, y);int pixel2 bitmap2.getPixel(x, y);int r1 Color.red(pixel1);int g1 Color.green(pixel1);int b1 Color.blue(pixel1);int r2 Color.red(pixel2);int g2 Color.green(pixel2);int b2 Color.blue(pixel2);// 计算 RGB 差异diff Math.abs(r1 - r2);diff Math.abs(g1 - g2);diff Math.abs(b1 - b2);}}// 最大可能差异double maxDiff 3L * 255 * width * height;// 返回 0 到 1 的值越小表示相似度越高return (double) diff / maxDiff; }这段代码计算两张图片的 RGB 差异返回的结果范围在 0-1 之间数值越接近 0 表示图片越相似。 2. 基于直方图的比较 通过比较两张图片的颜色直方图来评估相似度。直方图可以捕捉图像的颜色分布而不关心具体像素位置。 public static double compareHistograms(Bitmap bitmap1, Bitmap bitmap2) {int[] histogram1 new int[256];int[] histogram2 new int[256];// 计算两张图的灰度直方图for (int y 0; y bitmap1.getHeight(); y) {for (int x 0; x bitmap1.getWidth(); x) {int pixel1 bitmap1.getPixel(x, y);int gray1 (Color.red(pixel1) Color.green(pixel1) Color.blue(pixel1)) / 3;histogram1[gray1];int pixel2 bitmap2.getPixel(x, y);int gray2 (Color.red(pixel2) Color.green(pixel2) Color.blue(pixel2)) / 3;histogram2[gray2];}}// 计算直方图的差异double diff 0;for (int i 0; i 256; i) {diff Math.abs(histogram1[i] - histogram2[i]);}return diff / (bitmap1.getWidth() * bitmap1.getHeight()); }3. 使用 SSIM结构相似性 SSIM 是一种用来衡量两张图片结构相似性的算法它比简单的像素差异或直方图比较更准确。Android SDK 没有内置的 SSIM 方法但可以引入第三方库或者自己实现。SSIM 主要关注三方面亮度、对比度和结构。 4. 感知哈希pHash pHash 是一种图像哈希技术它可以生成图片的“指纹”然后比较两个哈希值的相似性。与传统哈希方法不同pHash 对于图像的细微改变例如缩放、旋转不敏感。 可以通过第三方库实现 pHash比如 ImageHash 库或者自己实现基于 DCT离散余弦变换的算法。 // 引入第三方库 ImageHash 进行哈希比较 String hash1 ImageHash.hash(bitmap1); String hash2 ImageHash.hash(bitmap2);int similarity ImageHash.compare(hash1, hash2);一般来说: 对于简单的图像比较基于像素差异的方式即可。如果要忽略图片的细微变动直方图或感知哈希是更合适的选择。SSIM 适用于对图像结构有更高要求的场景。 实现 图像比较的算法应用相当广泛, 本文基于感知哈希算法, 用于识别视频帧图像的左右两部分的相似度, 从而判断视频是否是一个左右眼的VR视频格式, 本文采用 感知哈希pHash 算法, 它非常适合处理具有细微变化的图像如裁剪、缩放、亮度变化等。 感知哈希pHash是一种用于衡量图像相似度的算法它通过将图像转换为频域信息提取其视觉特征来生成一个哈希值。pHash 具有鲁棒性能够忽略图像的小幅度变动、旋转和缩放等影响。下面是 pHash 算法的实现步骤及其原理。 pHash 算法的实现步骤 转换为灰度图将图片转换为灰度图像以便降低复杂度并去除颜色信息的影响。 缩小尺寸将图像缩小到一个固定的尺寸例如 32x32目的是去除高频细节保留图片的整体特征。这一步骤在后续的离散余弦变换DCT中很重要。 离散余弦变换DCT对缩小后的图像执行离散余弦变换将图像从空间域转换到频率域。这种转换能提取图像的低频信息忽略高频噪声。 截取低频部分只保留 DCT 结果的左上角部分例如 8x8 的矩阵因为这部分包含图像的主要信息。 计算均值计算截取的低频部分的均值。 生成哈希值将 DCT 中每个像素值与均值进行比较生成一个二进制序列。如果某个像素值大于均值置 1否则置 0。最终的哈希值是由这个二进制序列构成。 参考pHash 算法实现 import android.graphics.Bitmap; import android.graphics.Color; import java.util.Arrays;public class ImagePHash {// 默认使用 32x32 大小private static final int SIZE 32;// DCT 截取的大小例如 8x8private static final int SMALLER_SIZE 8;public String getHash(Bitmap img) {// 1. 转换为灰度图像Bitmap grayImg toGrayscale(img);// 2. 缩小图片Bitmap smallImg Bitmap.createScaledBitmap(grayImg, SIZE, SIZE, false);// 3. 转换为二维数组double[][] vals new double[SIZE][SIZE];for (int x 0; x SIZE; x) {for (int y 0; y SIZE; y) {vals[x][y] Color.red(smallImg.getPixel(x, y));}}// 4. 对图像执行离散余弦变换DCTdouble[][] dctVals applyDCT(vals);// 5. 截取 DCT 左上角的 8x8 部分double[] dctLowFreq new double[SMALLER_SIZE * SMALLER_SIZE];for (int x 0; x SMALLER_SIZE; x) {for (int y 0; y SMALLER_SIZE; y) {dctLowFreq[x * SMALLER_SIZE y] dctVals[x][y];}}// 6. 计算均值double avg Arrays.stream(dctLowFreq).average().orElse(0.0);// 7. 生成哈希值StringBuilder hash new StringBuilder();for (double value : dctLowFreq) {hash.append(value avg ? 1 : 0);}return hash.toString();}// 转换为灰度图像private Bitmap toGrayscale(Bitmap img) {int width img.getWidth();int height img.getHeight();Bitmap grayscaleImg Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);for (int y 0; y height; y) {for (int x 0; x width; x) {int pixel img.getPixel(x, y);int red Color.red(pixel);int green Color.green(pixel);int blue Color.blue(pixel);int gray (red green blue) / 3;int newPixel Color.rgb(gray, gray, gray);grayscaleImg.setPixel(x, y, newPixel);}}return grayscaleImg;}// 执行离散余弦变换DCTprivate double[][] applyDCT(double[][] f) {int N f.length;double[][] F new double[N][N];for (int u 0; u N; u) {for (int v 0; v N; v) {double sum 0.0;for (int i 0; i N; i) {for (int j 0; j N; j) {sum f[i][j] *Math.cos((2 * i 1) * u * Math.PI / (2.0 * N)) *Math.cos((2 * j 1) * v * Math.PI / (2.0 * N));}}double alphaU (u 0) ? Math.sqrt(1.0 / N) : Math.sqrt(2.0 / N);double alphaV (v 0) ? Math.sqrt(1.0 / N) : Math.sqrt(2.0 / N);F[u][v] alphaU * alphaV * sum;}}return F;}// 比较两个哈希值返回汉明距离不同位数的个数public int hammingDistance(String hash1, String hash2) {int distance 0;for (int i 0; i hash1.length(); i) {if (hash1.charAt(i) ! hash2.charAt(i)) {distance;}}return distance;} }对比效果如下(使用ListView 显示多张图片对比结果, 一帧视频图像从中间切割左右两部分, 分别显示在列表项的左右两侧, 中间的文字输出比较结果的汉明值, 值越小图像差异越小): 原始测试图片(从一个VR视频中截取出的视频帧): 代码分享: test_img_diff.xml 布局 ?xml version1.0 encodingutf-8? RelativeLayout xmlns:androidhttp://schemas.android.com/apk/res/androidandroid:layout_widthmatch_parentandroid:layout_heightmatch_parentandroid:idid/rlRootListView android:idid/lvandroid:layout_widthmatch_parentandroid:layout_heightmatch_parent/ /RelativeLayoutListView 的item 布局: item_img_diff.xml ?xml version1.0 encodingutf-8? RelativeLayout xmlns:androidhttp://schemas.android.com/apk/res/androidandroid:layout_widthmatch_parentandroid:layout_heightmatch_parentImageView android:idid/ivLeftandroid:layout_width128dpandroid:layout_height72dp/ImageView android:idid/ivRightandroid:layout_width128dpandroid:layout_height72dpandroid:layout_alignParentRighttrue/TextView android:idid/tvResandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:layout_centerInParenttrueandroid:textSize18spandroid:textColor#FFFFFFFF/ /RelativeLayout主界面Activity: ImgDiffTester.java public class ImgDiffTester extends Activity implements View.OnClickListener {final String TAG ImgDiffTester;ListView lv;ImgListAdapter adapter;Overrideprotected void onCreate(Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.test_img_diff);findViewById(R.id.rlRoot).setOnClickListener(this);lv (ListView) findViewById(R.id.lv);adapter new ImgListAdapter();lv.setAdapter(adapter);startCompare();}void startCompare(){new Thread(){Overridepublic void run() {File[] fs new File(/sdcard/Download/).listFiles(new FileFilter() {Overridepublic boolean accept(File file) {return file.getName().endsWith(.png);}});for(File f : fs){Bitmap bm BitmapFactory.decodeFile(f.getAbsolutePath());compareBitmapAndShow(bm);}lv.post(new Runnable() {Overridepublic void run() {adapter.notifyDataSetChanged();}});}}.start();}void compareBitmapAndShow(Bitmap bm){if(bm ! null bm.getWidth() 0 bm.getHeight() 0) {final Bitmap bm1 BitmapUtils.clipBitmapWidthBounds(bm, new Rect(0, 0, bm.getWidth() / 2, bm.getHeight()));//bm1 BitmapFactory.decodeFile(/sdcard/l.png);final Bitmap bm2 BitmapUtils.clipBitmapWidthBounds(bm, new Rect(bm.getWidth() / 2, 0, bm.getWidth(), bm.getHeight()));//bm2 BitmapFactory.decodeFile(/sdcard/r.png);try {Bitmap[] scaled new Bitmap[2];//scaled[0] Bitmap.createBitmap(pHash.DCT_LENGTH, pHash.DCT_LENGTH, Bitmap.Config.ARGB_8888);//scaled[1] Bitmap.createBitmap(pHash.DCT_LENGTH, pHash.DCT_LENGTH, Bitmap.Config.ARGB_8888);//int cmp pHash.compareBitmap(bm1, bm2, scaled, false);long st SystemClock.uptimeMillis();final int cmp ImagePHash.compareBitmap(bm1, bm2);long et SystemClock.uptimeMillis();Log.d(TAG, compare cmp spend (et - st) ms);Item item new Item();item.l bm1;item.r bm2;item.res Result: cmp , spend (et - st) ms;adapter.items.add(item);} catch (Exception e) {throw new RuntimeException(e);}}}public static class ImagePHash {// 默认使用 32x32 大小private static final int SIZE 32;// DCT 截取的大小例如 8x8private static final int SMALLER_SIZE 8;public static int compareBitmap(Bitmap bm1, Bitmap bm2){String h1 getHash(bm1);String h2 getHash(bm2);return hammingDistance(h1, h2);}SuppressLint(NewApi)public static String getHash(Bitmap img) {long st SystemClock.uptimeMillis();// 1. 转换为灰度图像Bitmap grayImg toGrayscale(img);// 2. 缩小图片Bitmap smallImg Bitmap.createScaledBitmap(grayImg, SIZE, SIZE, false);// 3. 转换为二维数组double[][] vals new double[SIZE][SIZE];for (int x 0; x SIZE; x) {for (int y 0; y SIZE; y) {vals[x][y] Color.red(smallImg.getPixel(x, y));}}long ct1 SystemClock.uptimeMillis();// 4. 对图像执行离散余弦变换DCTdouble[][] dctVals applyDCT(vals);long ct2 SystemClock.uptimeMillis();// 5. 截取 DCT 左上角的 8x8 部分double[] dctLowFreq new double[SMALLER_SIZE * SMALLER_SIZE];for (int x 0; x SMALLER_SIZE; x) {for (int y 0; y SMALLER_SIZE; y) {dctLowFreq[x * SMALLER_SIZE y] dctVals[x][y];}}// 6. 计算均值double avg Arrays.stream(dctLowFreq).average().orElse(0.0);long ct3 SystemClock.uptimeMillis();// 7. 生成哈希值StringBuilder hash new StringBuilder();for (double value : dctLowFreq) {hash.append(value avg ? 1 : 0);}Log.d(ImgDiff, (ct1 - st) , (ct2 - ct1));return hash.toString();}// 转换为灰度图像private static Bitmap toGrayscale(Bitmap img) {int width img.getWidth();int height img.getHeight();Bitmap grayscaleImg Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);for (int y 0; y height; y) {for (int x 0; x width; x) {int pixel img.getPixel(x, y);int red Color.red(pixel);int green Color.green(pixel);int blue Color.blue(pixel);int gray (red green blue) / 3;int newPixel Color.rgb(gray, gray, gray);grayscaleImg.setPixel(x, y, newPixel);}}return grayscaleImg;}// 执行离散余弦变换DCTprivate static double[][] applyDCT(double[][] f) {int N f.length;double[][] F new double[N][N];for (int u 0; u N; u) {for (int v 0; v N; v) {double sum 0.0;for (int i 0; i N; i) {for (int j 0; j N; j) {sum f[i][j] *Math.cos((2 * i 1) * u * Math.PI / (2.0 * N)) *Math.cos((2 * j 1) * v * Math.PI / (2.0 * N));}}double alphaU (u 0) ? Math.sqrt(1.0 / N) : Math.sqrt(2.0 / N);double alphaV (v 0) ? Math.sqrt(1.0 / N) : Math.sqrt(2.0 / N);F[u][v] alphaU * alphaV * sum;}}return F;}// 比较两个哈希值返回汉明距离不同位数的个数public static int hammingDistance(String hash1, String hash2) {int distance 0;for (int i 0; i hash1.length(); i) {if (hash1.charAt(i) ! hash2.charAt(i)) {distance;}}return distance;}}class ImgListAdapter extends BaseAdapter{ArrayListItem items new ArrayList();Overridepublic int getCount() {return items.size();}Overridepublic Object getItem(int i) {return items.get(i);}Overridepublic long getItemId(int i) {return i;}Overridepublic View getView(int pos, View view, ViewGroup viewGroup) {if(view null){view getLayoutInflater().inflate(R.layout.item_img_diff, null, false);}((ImageView)view.findViewById(R.id.ivLeft)).setImageBitmap(items.get(pos).l);((ImageView)view.findViewById(R.id.ivRight)).setImageBitmap(items.get(pos).r);((TextView)view.findViewById(R.id.tvRes)).setText(items.get(pos).res);return view;}}class Item{Bitmap l, r;String res;} }温馨提示 本文算法及用例仅供参考, 未经大量测试验证 请谨慎阅读参考 参考 Android Bitmap亮度调节、灰度化、二值化、相似距离实现
http://www.w-s-a.com/news/926729/

相关文章:

  • 班级网站 建设目标如何做好网站建设内容的策划书
  • 网站建设与网页设计期末考试清博舆情系统
  • plone网站开发商城网站建设怎么收费
  • 旺旺号查询网站怎么做公司门户网站项目模版
  • 网站免费一站二站四站上海网站怎么备案表
  • 漫画交流网站怎么做开发微信小程序公司
  • 网站建设马鞍山怎么建立局域网网站
  • 开源 网站开发框架哪些网站可以做图片链接
  • 大良制作网站网站设计的能力要求
  • 前端设计除了做网站还能做什么江苏高校品牌专业建设工程网站
  • 做二手房产网站多少钱用户权限配置wordpress
  • 做亚马逊网站需要租办公室吗小型企业网站模板
  • 网站全屏视频怎么做个人公司注册网上申请
  • 如何k掉别人的网站搜索引擎优化与关键词的关系
  • 百度推广 网站吸引力做网站开发的薪酬怎么样
  • js网站开发工具软件营销方案
  • 做网站的天空网云南省建设厅网站怎么进不去
  • 天津网站排名提升网络营销推广策略包括哪些
  • 网站建设与管理 ppt网站打开是别人的
  • 图片网站怎么做排名怎么分析一个网站seo
  • 伪原创对网站的影响深圳装修公司排名100强
  • 网站建设公司效果个人可以做医疗信息网站吗
  • 网站使用arial字体下载微网站 建设
  • 文化馆网站建设意义营销型国外网站
  • 公司网站定位建议wordpress怎么用模板
  • 中国十大热门网站排名计算机选什么专业最好
  • 怀化建设企业网站太原网站关键词排名
  • 空间注册网站网站制作是怎么做的
  • 数码家电商城网站源码一个网站的成本
  • 网站伪静态是什么意思麻涌东莞网站建设