博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
『原创』+『参考』基于PPC的图像对比程序——使用直方图度量
阅读量:6330 次
发布时间:2019-06-22

本文共 3688 字,大约阅读时间需要 12 分钟。

前言的前言:

最近小弟闲来无聊,就想到了在PPC上面来做个图像对比的小东东,查找各方资料,终于在今天初步完成了这个程序,现在整理之后和各位共勉。程序中还存在很多不足之处,大家尽管提出自己的意见和建议,本人非常欢迎哦!

前言:

在阅读本文后,你将知道:

  • 如何在.net Compact Framework 2.0框架下使用C#语言进行图片的缩放操作、保存
  • 如何在c#中计算图片的直方图量度
  • 如何使用SelectPictureDialog对话框

你需要以下开发环境:

  1. Visual Studio 2008
  2. Windows Mobile 6 Professional SDK(WM6可以直接运行我提供的例子,WM5也可以开发

正文:

第一步:我们先来创建一个C# 智能设备项目,我选用的是.net Compact Framework 2.0的框架库,然后选择 Windows Mobile 6 Professional SDK 平台。

在默认的Form1窗体中,我们如下图一样进行设计:

一个Label2用于显示对比结果、一个TabControl,tabPage1中有一个PictureBox1,tabPage2中同样放入一个PictureBox2,两个PictureBox的SizeMode属性设置为StretchImage。

设计好界面后,我们就添加代码,在这里只列出关键代码,详细代码请到下载的项目中查找吧。

在程序头部引用

using Microsoft.WindowsMobile.Forms;

using System.Drawing;

然后,添加全局变量:

PicCompare.GetHisogram.GetHis getHis = new PicCompare.GetHisogram.GetHis();//直方图度量计算类其中包括了图像缩放方法

string pic1 = @"Storage Card/test.bmp";//指定缩放后的图片存放位置和格式
string pic2 = @"Storage Card/test2.bmp";//指定缩放后的图片存放位置和格式
int[] pic1t;//图片一的直方图量度容器
int[] pic2t;//图片二的直方图量度容器

定义好变量后,我们双击“图片一”,给他添加如下代码:

 

Code
SelectPictureDialog spd = new SelectPictureDialog();
spd.ShowDialog();
pic1t 
= getHis.GetHisogram(getHis.Resized(spd.FileName, pic1));//计算出图片一的直方图量度存放到一个pic1t的数组变量中
Bitmap bmp=new Bitmap(spd.FileName);
            
pictureBox1.Image 
= bmp;//把处理后的图片放入pictureBox1进行预览

 

图片二按钮同上,只需修改相关参数即可。

然后我们看一下直方图量度计算类的部分代码实现吧:

计算图像的直方图的这个代码从网络上copy过来的,这个到处都有,我也不是太在行,所以暂不做解释了,汗~

计算图像的直方图
 /// <summary>
        
/// 计算图像的直方图
        
/// </summary>
        
/// <param name="img">图片</param>
        
/// <returns>返回直方图量度</returns>
        public int[] GetHisogram(Bitmap img)
        {
            
            BitmapData data 
= img.LockBits(new System.Drawing.Rectangle(00, img.Width, img.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
            
int[] histogram = new int[256];
            
unsafe
            {
                
byte* ptr = (byte*)data.Scan0;
                
int remain = data.Stride - data.Width * 3;
                
for (int i = 0; i < histogram.Length; i++)
                    histogram[i] 
= 0;
                
for (int i = 0; i < data.Height; i++)
                {
                    
for (int j = 0; j < data.Width; j++)
                    {
                        
int mean = ptr[0+ ptr[1+ ptr[2];
                        mean 
/= 3;
                        histogram[mean]
++;
                        ptr 
+= 3;
                    }
                    ptr 
+= remain;
                }
            }
            img.UnlockBits(data);
            
return histogram;
        }

 

下面的这个代码就是在分别计算完两张图片的量度后,把两个量度再放到这里面来计算结果,所得结果即为图片相似度的一个参考值,代码如下:

 

最终计算结果
        /// <summary>
        
///最终计算结果
        
/// </summary>
        
/// <param name="firstNum">图片一的直方图量度</param>
        
/// <param name="scondNum">图片二的直方图量度</param>
        
/// <returns>计算结果</returns>
        public float GetResult(int[] firstNum, int[] scondNum)
        {
            
if (firstNum.Length != scondNum.Length)
            {
                
return 0;
            }
            
else
            {
                
float result = 0;
                
int j = firstNum.Length;
                
for (int i = 0; i < j; i++)
                {
                    result 
+= 1 - GetAbs(firstNum[i], scondNum[i]);
                    Console.WriteLine(i 
+ "----" + result);
                }
                
return result / j;
            }
        }

 

其中,还有一个类是用来处理图片大小的,在这里也贴出来,大家应该用得到的哦!

 

Code
 /// <summary>
        
/// 图片大小缩放(正方形)
        
/// 作者:Jack Fan
        
/// </summary>
        
/// <param name="sideSize">指定大小</param>
        
/// <param name="srcBMP">原始图片</param>
        
/// <returns>返回缩放后的Bitmap图片</returns>
        public Bitmap ResizeBMP(int sideSize, Bitmap srcBMP)
        {
            Bitmap bmp 
= new Bitmap(sideSize, sideSize);
            Rectangle srcRec 
= new Rectangle(00, srcBMP.Width, srcBMP.Height);
            Rectangle destRec 
= new Rectangle(00, sideSize, sideSize);
            Graphics g 
= Graphics.FromImage(bmp);
            g.DrawImage(srcBMP, destRec, srcRec, GraphicsUnit.Pixel);
            g.Dispose();
            
return bmp;
        }

 

 

对比按钮的代码:

 

对比按钮
 pictureBox1.Refresh();
pictureBox2.Refresh();
label2.Text 
= (getHis.GetResult(pic1t, pic2t) * 100).ToString() + "%";//计算最终结果

 

好了,代码就是这些了,下面来看看实际效果如何把:

1、程序运行后,添加了两张比较相似的图片(不同点请看第三张图片的红圈):

然后,点击“对比”按钮后,即可见到相似度了:

 

结尾:

在这里,我想申明一点,这个直方图量度来计算图片相似度的想法是我从园子里一个朋友的blog上看来的,本想在前面附上他的署名,无奈今天无论如何都找不到他的原文,所以请见谅,您看到了就跟我说一声,毕竟我还有很多问题想请教一二啊!(原文名称《图像相似度算法的C#实现及测评》,在cnblogs里面好像搜不到了哦,大家股沟一下吧!)文中还有部分细节描述不清楚的地方,欢迎各位提问,在下文笔不好,只能是有问必答,呵呵。相信大家在看了源代码以及了解了相关直方图量度的知识后,会有另一番感觉。

另:在测试中,发现如果使用图片分割,再逐个部分进行对比,然后在汇总的方法,得出的结果就比较高了!但是无奈PPC设备硬件条件有限,暂时还不考虑。如果转载请注明原文归属哦,谢谢。

 源代码:

你可能感兴趣的文章
利用Shell开发跳板机功能脚本案例
查看>>
51CTO的技术门诊谈OSSIM
查看>>
六年心路成长 —— 做自己
查看>>
Unix整理笔记——高级命令sed和awk——里程碑M10
查看>>
Linux系统详解 第六篇:系统的启动、登录、注销与开关机
查看>>
ios电话拨打进行监听电话状态
查看>>
京东基于Spark的风控系统架构实践和技术细节
查看>>
什么时候使用CountDownLatch
查看>>
C#之MemberwiseClone与Clone
查看>>
Android性能优化之利用Rxlifecycle解决RxJava内存泄漏
查看>>
转: 如何为你的开源项目选择一个合适的开源协议?
查看>>
关系型数据库和NOSQL数据库对比
查看>>
Atitit 记录方法调用参数上下文arguments
查看>>
webstorm常用功能FTP,及常用快捷键
查看>>
eclipse html 打开方式
查看>>
[求助] win7 x64 封装 出现 Administrator.xxxxx 的问题
查看>>
人类投资经理再也无法击败电脑的时代终将到来了...
查看>>
一个最小手势库的实现
查看>>
HoloLens开发手记 - Vuforia开发概述 Vuforia development overview
查看>>
Android支付之支付宝封装类
查看>>