小程序图像处理
2018-09-24 04:06:06 weixin_34220179 阅读数 143

背景

小程序的canvas是微信基于原生组件自行封装的,因此接口跟web的canvas有不少区别,早期更是没有支持像素级的处理能力。
在18年初的小程序基础库1.9.0版本更新中,出现了wx.canvasGetImageData和wx.canvasPutImageData两个重要的API,补全了像素处理能力,因此,小程序在客户端进行图片处理成为了可能。
具体可以参考:
偷偷迭代的重磅功能---小程序的像素处理能力
wx.canvasGetImageData

图片配色分析小程序:小色卡

为了尝试小程序的图像处理能力,我做了个用于图片配色分析的小程序-小色卡。
功能主要是:用户选择一张图片,程序会分析图片的配色,并把配色展示为一张色卡给用户。用户可以保存、编辑、复制自己的色卡。这个功能对初级的UI设计师有一定的帮助(可能吧...)。
源码:github:mini-color-card
体验小程序:
小色卡

原理

小程序实现配色分析主要步骤如下:

  1. 用户选择图片,拿到imgPath后绘制到canvas上。
  2. 通过wx.canvasGetImageData这个接口读取图片数据
  3. 对图片数据进行预处理,剔除alpha比较小并且不是白色的点。(非必要)
  4. 对图片像素数据进行聚类。每个像素的颜色可以作为一个三维向量来看。

基本逻辑如下:

wx.chooseImage({
  count: 1,
  sizeType: ['original', 'compressed'],
  sourceType: ['album', 'camera'],
  success: (res) => {
    wx.getImageInfo({
      src: res.tempFilePaths[0],
      success: (imgInfo) => {
        let {
          width,
          height,
          imgPath
        } = imgInfo;
        let ctx = wx.createCanvasContext(this.canvasID);
        ctx.drawImage(imgPath,0,0,width,height);
        ctx.draw(false,()=>{
          wx.canvasGetImageData({
            canvasId: this.canvasID,
            x: 0,
            y: 0,
            width: width,
            height: height,
            success(res) {
              var pixels = res.data;
              var pixelCount = width*height;
              var pixelArray = [];
              // 对像素数据进行预处理
              for (var i = 0, offset, r, g, b, a; i < pixelCount; i = i + quality) {
                offset = i * 4;
                r = pixels[offset + 0];
                g = pixels[offset + 1];
                b = pixels[offset + 2];
                a = pixels[offset + 3];
                if (a >= 125) {
                  if (!(r > 250 && g > 250 && b > 250)) {
                    pixelArray.push([r, g, b]);
                  }
                }
              }
              var cmap = MMCQ.quantize(pixelArray, colorCount);//聚类,MMCQ是个用于图像分析的库
              var palette = cmap ? cmap.palette() : null;
              console.log('配色为:',palette);
            }
          })
        })
      }
    })
  }
})

小结

一开始我是不想把canvas显示出来的,只想用它获取图像内容,但是实践下来是不可行的。小程序的canvas并不允许离屏渲染,想要用它进行图片处理,就要老老实实用它进行展示。
这里只实践了wx.canvasGetImageData读取数据进行图像分析,不过结合wx.canvasPutImageData,滤镜之类的图像处理应该都是可以做了。小程序的想象空间还是挺大的。

2005-12-12 22:30:00 weixin_33778778 阅读数 85
    功能很简单,主要为了熟悉一下图像处理的基本操作!
    主要功能在一个封装好的类中,功能还写了蛮多的。
    截了几个图,
    源代码 (要的人比较多,所以还是把源代码传了上来)
 

截图1.JPG截图2.JPG截图3.JPG截图4.JPG
2007-07-21 20:07:00 metababy 阅读数 2060
图像处理 和 格式转换 小程序 (1)

    功能很简单,主要为了熟悉一下图像处理的基本操作!
    主要功能在一个封装好的类中,功能还写了蛮多的。
    截了几个图,
    源代码 (要的人比较多,所以还是把源代码传了上来)
 

截图1.JPG截图2.JPG截图3.JPG截图4.JPG 

 

图像处理(2)--简单的效果处理
本文主要说说几种简单图像效果处理的原理和实现

重要源码都贴出来了,如果需要所有源码的留下Email吧

原图效果:


一、反色:
         图像反色实际上就是取没一个像素点的相对颜色值
 比如图像某点像素RGB(128,52,38),则它的反色值为RGB(127,203,217)
 

http://blog.csdn.net/metababy

http://hexun.com/metababy

        /// <summary>
        
/// 以反色方式显示图像    
        
/// </summary>
        
/// <param name="SImage">源图像</param>
        
/// <returns>反色处理后的图像</returns>

        public Bitmap fanSe(Image SImage)
        
{            
            
int Height = SImage.Height;
            
int Width = SImage.Width;
            Bitmap bitmap
=new Bitmap(Width,Height);
            Bitmap MyBitmap
=(Bitmap)SImage;
            Color pixel;
            
for(int x=1;x<Width;x++)
            
{
                
for(int y=1;y<Height;y++)
                
{
                    
int r,g,b;
                    pixel
=MyBitmap.GetPixel(x,y);                    
                    r
=255-pixel.R;
                    g
=255-pixel.G;
                    b
=255-pixel.B;
                    bitmap.SetPixel(x,y,Color.FromArgb(r,g,b));            
                }

            }

            
return bitmap;            
        }



二、浮雕:
        通过对图像相邻像素点的像素值分别与相邻像素点的像素值相减之后加上一个常量128,然后作为新的像素点值(为防止颜色值溢出,需处理值小于0和大于255的情况颜色值),可以使图像产生浮雕效果

 

        /// <summary> 
        
///以浮雕方式显示图像        
        
/// </summary>
        
/// <param name="SImage">源图像</param>
        
/// <returns>浮雕效果处理后的图像</returns>

        public Bitmap fuDiao(Image SImage)
        
{    
            
int Height = SImage.Height;
            
int Width = SImage.Width;
            Bitmap bitmap
=new Bitmap(Width,Height);
            Bitmap MyBitmap
=(Bitmap)SImage;
            Color pixel1,pixel2;
            
for(int x=0;x<Width-1;x++)
            
{
                
for(int y=0;y<Height-1;y++)
                
{
                    
int r=0,g=0,b=0;
                    pixel1
=MyBitmap.GetPixel(x,y);                        
                    pixel2
=MyBitmap.GetPixel(x+1,y+1);
                    r 
= pixel1.R-pixel2.R+128;
                    g 
= pixel1.G-pixel2.G+128;
                    b 
= pixel1.B-pixel2.B+128;
                    
if(r>255)
                        r
=255;
                    
if(r<0)
                        r
=0;
                    
if(g>255)
                        g
=255;
                    
if(g<0)
                        g
=0;
                    
if(b>255)
                        b
=255;
                    
if(b<0)
                        b
=0;
                    bitmap.SetPixel(x,y,Color.FromArgb(r,g,b));            
                }

            }

            
return bitmap;        
        }



三、黑白化处理:
        彩色图像黑白化处理通常有三种方法:最大值法、平均值法、加权平均值法
三种方法的原理
        最大值法:最大值法是每个像素点的RGB值等于原像素点的RGB值中最大的一个,
                            即R=G=B=MAX( R,G,B ); 效果,最大值发产生亮度很高的黑白图像
        平均值法:平均值法使每个像素点的RGB值等于原像素点的RGB值的平均值,即R=G=B=(R+G+B)/3 
        加权平均法:加权平均法根据需要指定每个像素点RGB的权数,并取其加权平均值,
                                即R=G=B=(Wr*R+Wg*G+Wb*B )/3 
                                Wr、Wg、Wb表示RGB的权数,均大于零,通过取不同的权数可实现不同的效果

        /// <summary>
        
/// 以黑白方式显示图像
        
/// </summary>
        
/// <param name="SImage">源图像</param>
        
/// <param name="iType">黑白处理的方法参数,0-平均值法;1-最大值法;2-加权平均值法</param>
        
/// <returns></returns>

        public Bitmap heiBai(Image SImage,int iType)
        
{        
            
int Height = SImage.Height;
            
int Width = SImage.Width;
            Bitmap bitmap
=new Bitmap(Width,Height);
            Bitmap MyBitmap
=(Bitmap)SImage;
            Color pixel; 
            
for (int x=0; x<Width; x++
                
for (int y=0; y<Height; y++
                
{
                    pixel
=MyBitmap.GetPixel(x,y);
                    
int r,g,b,Result=0;
                    r 
= pixel.R;                            
                    g 
= pixel.G;                
                    b 
= pixel.B;    
                    
                    
switch(iType)
                    
{
                        
case 0://平均值法
                            Result=((r+g+b)/3);
                            
break;
                        
case 1://最大值法
                            Result=r>g?r:g;
                            Result
=Result>b?Result:b;
                            
break;
                        
case 2://加权平均值法
                            Result=((int)(0.7*r)+(int)(0.2*g)+(int)(0.1*b));
                            
break;
                    }

                    bitmap.SetPixel(x,y,Color.FromArgb(Result,Result,Result));
                }
     
            
return bitmap;        
        }

 

四、柔化:
        柔化显示图像和锐化显示图像的操作刚好相反,但在算法上不是它的逆过程。它的主要思想是减少图像边缘值之间的剧烈变化。
        当将当前像素点的颜色值设为以该像素为中心的像素块中所有像素的平均值时,如果当前像素点的颜色值和周围相邻像素点的颜色值差别不大时,则取平均值不会产生显著影响;如果差别较大时,取平均值后,就会使当前像素点的颜色趋于一致,这样就达到了柔化图像的目的。也称这种方法为高斯模板

        /// <summary>
        
/// 以柔化方式显示图像    
        
/// </summary>
        
/// <Note>高斯模板法</Note>
        
/// <param name="SImage">源图像</param>
        
/// <returns>柔化处理后的图像</returns>

        public Bitmap rouHua(Image SImage)
        
{
            
int Height = SImage.Height;
            
int Width = SImage.Width;
            Bitmap bitmap
=new Bitmap(Width,Height);
            Bitmap MyBitmap
=(Bitmap)SImage;
            Color pixel;
            
//高斯模板
            int []Gauss={1,2,1,2,4,2,1,2,1};                                
            
for(int x=1;x<Width-1;x++)
                
for(int y=1;y<Height-1;y++)
                
{
                    
int r=0,g=0,b=0;
                    
int Index=0;
                    
//int a=0;
                    for(int col=-1;col<=1;col++)
                        
for(int row=-1;row<=1;row++)
                        
{                            
                            pixel
=MyBitmap.GetPixel(x+row,y+col);                        
                            r
+=pixel.R*Gauss[Index];
                            g
+=pixel.G*Gauss[Index];
                            b
+=pixel.B*Gauss[Index];
                            Index
++;
                        }

                    r
/=16;
                    g
/=16;
                    b
/=16;
                    
//处理颜色值溢出
                    r=r>255?255:r;
                    r
=r<0?0:r;
                    g
=g>255?255:g;
                    g
=g<0?0:g;
                    b
=b>255?255:b;
                    b
=b<0?0:b;
                    bitmap.SetPixel(x
-1,y-1,Color.FromArgb(r,g,b));            
                }

            
return bitmap;        
        }




五、锐化:
        图像的锐化就是要显示图像中有关形体的边缘。所谓形体的边缘就是图像像素点的颜色值发生显著变化的地方,在图像的平淡区,这种颜色值的变化比较平缓,而在图像的边缘区域这种变化相当明显。
也就是说在平缓区,相邻两像素的颜色值的差值较小,而在边缘区域,相邻两像素的颜色值变化抖得多,因而在边缘区域处理这个数值可以使突出效果更加突出,而在非边缘区域而使图像变得较暗,即图像的锐化。拉普拉斯模块法

        /// <summary>
        
/// 以锐化方式显示图像        
        
/// </summary>
        
/// <Note>拉普拉斯模板法</Note>
        
/// <param name="SImage">源图像</param>
        
/// <returns>锐化处理后的图像</returns>

        public Bitmap ruiHua(Image SImage)
        
{
            
int Height=SImage.Height;
            
int Width=SImage.Width;
            Bitmap bitmap
=new Bitmap(Width,Height);
            Bitmap MyBitmap
=(Bitmap)SImage;
            Color pixel;
            
//拉普拉斯模板
            int []Laplacian={-1,-1,-1,-1,9,-1,-1,-1,-1};               
            
for(int x=1;x<Width-1;x++)
                
for(int y=1;y<Height-1;y++)
                
{
                    
int r=0,g=0,b=0;
                    
int Index=0;
                    
int a=0;
                    
for(int col=-1;col<=1;col++)
                        
for(int row=-1;row<=1;row++)
                        
{                            
                            pixel
=MyBitmap.GetPixel(x+row,y+col);                        
                            r
+=pixel.R*Laplacian[Index];
                            g
+=pixel.G*Laplacian[Index];
                            b
+=pixel.B*Laplacian[Index];
                            Index
++;
                        }

                    
//处理颜色值溢出
                    r=r>255?255:r;
                    r
=r<0?0:r;
                    g
=g>255?255:g;
                    g
=g<0?0:g;
                    b
=b>255?255:b;
                    b
=b<0?0:b;
                    bitmap.SetPixel(x
-1,y-1,Color.FromArgb(r,g,b));            
                }

            
return bitmap;        
        }



六、雾化:
        图像雾化处理不是基于图像中像素点的运算,而是在图像中引入一定的随机性,使图像带有毛玻璃带水雾般的效果。
        影响图像雾化效果的一个重要因素是图像中像素块的确定,所选区的像素块越大,产生的效果越明显。
 

        /// <summary>
        
/// 以雾化方式显示图像
        
/// </summary>
        
/// <param name="SImage"></param>
        
/// <returns></returns>

        public Bitmap wuHua(Image SImage)
        
{        
            
int Height=SImage.Height;
            
int Width=SImage.Width;
            Bitmap bitmap
=new Bitmap(Width,Height);
            Bitmap MyBitmap
=(Bitmap)SImage;
            Color pixel;                                            
            
for(int x=1;x<Width-1;x++)
                
for(int y=1;y<Height-1;y++)
                
{
                    System.Random   MyRandom
=new Random();                    
                    
int k=MyRandom.Next(123456);    
                    
//像素块大小
                    int dx=x+k%19;
                    
int dy=y+k%19;
                    
if(dx>=Width)
                        dx
=Width-1;
                    
if(dy>=Height)
                        dy
=Height-1;
                    pixel
=MyBitmap.GetPixel(dx,dy);
                    bitmap.SetPixel(x,y,pixel);            
                }

            
return bitmap;        
        }
2018-01-16 20:14:00 weixin_34270606 阅读数 9

梯度/梯度算子:这里的梯度特指二维离散函数中的梯度,因此就不能用连续函数的算法计算,而是要用差分的方法。计算方法有很多种,常见的两种其一是G(x,y) = dx(i,j) + dy(i,j); 其中dx(i,j) = H(i+1,j) - H(i,j); dy(i,j) = H(i,j+1) - H(i,j);,或者使用中值差分,即dx(i,j) = (H(i+1,j) - H(i-1,j)) / 2; dy(i,j) = (H(i,j+1) - H(i,j-1)) / 2;。在图像处理中,计算梯度通常使用卷积的方式来求得,卷积核被称为算子。通常一阶导数算子(梯度算子)用于在边缘灰度值过度比较尖锐、图像噪声比较小时,而二阶导数算子(拉普拉斯算子)用于确定已知边缘像素后像素在明区还是暗区。

Hough变换:把图像平面上的点对应到参数平面上的线,最后通过统计特性(假如是直线就统计线的交点个数,参数平面下交点的坐标就是斜率和截距,对应图像平面就是一条线)

2015-07-28 10:06:15 u014616233 阅读数 391
po主从今天开始做图像匹配方面的研究,每天把自己学到的新东西放上来,当做是记录自己成长的足迹吧,加油
没有更多推荐了,返回首页