• 微信小程序中的图片处理 微信小程序中的用于向页面插入图片。有两个重要的属性 1、src 要插入图片的资源地址 2、mode 图片裁剪、缩放的模式 下面仔细说一下mode属性 当我们不知道获取到图片的宽高或者...

    微信小程序中的图片处理

    微信小程序中的<image></image>用于向页面中插入图片。有两个重要的属性
    1、src  要插入图片的资源地址
    2、mode   图片裁剪、缩放的模式

    下面仔细说一下mode属性
    当我们不知道获取到图片的宽高或者需要对图片进行一些处理时,这个属性十分有用!
    mode属性为大家提供了4 种是缩放模式,9 种是裁剪模式。
    缩放模式:
    (1)scaleToFill  不保持纵横比缩放。也就是图片会填满你所设置的<image>组件的宽高。
    (2)aspectFit  保持纵横比缩放,使图片的长边能完全显示出来。也就是说,可以完整地将图片显示出来
    (3)aspectFill  保持纵横比缩放,只保证图片的短边能完全显示出来。也就是说,图片通常只在水平或垂直方向是完整的,另一个方向将会发生截取。这时小程序是采用截取图片中间部分的形式。
    一张图片 宽175px (长边)高150px(短边)

    如果image组件设置的宽高为  宽200px 高200px,为了让图片的短边全部显示出来,图片的短边会放大到200px,还要保持纵横比,长边也会按照一定的比例放大。但是长边多余的部分会被截取。

    可以看到对于长边的截取方式是中间的那一部分,掐头去尾。

    (4)widthFix   宽度不变,高度自动变化,保持原图宽高比不变


    裁剪模式

    裁剪模式比较简单。下面是官方文档的解释

    bottom 不缩放图片,只显示图片的底部区域
    center 不缩放图片,只显示图片的中间区域
    left 不缩放图片,只显示图片的左边区域
    right 不缩放图片,只显示图片的右边区域
    top left 不缩放图片,只显示图片的左上边区域
    top right 不缩放图片,只显示图片的右上边区域
    bottom left 不缩放图片,只显示图片的左下边区域
    bottom right 不缩放图片,只显示图片的右下边区域
    还有需要注意的之前我们说过的裁剪和缩放都是在指定了<image>组件宽高的情况。小程序中默认<image>的宽度300px、高度225px

    但是当我们进行裁剪和缩放时会发现,小程序中给出的默认宽度却是320px

    还有就是缩放和裁剪不会同时作用到一张图片上



    展开全文
  • 背景 小程序的canvas是微信基于原生组件自行...在18年初的小程序基础库1.9.0版本更新,出现了wx.canvasGetImageData和wx.canvasPutImageData两个重要的API,补全了像素处理能力,因此,小程序在客户端进行图片处理...
        

    背景

    小程序的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,滤镜之类的图像处理应该都是可以做了。小程序的想象空间还是挺大的。

    展开全文
  • 数字图像处理对数学的要求颇高,这不禁令很多学习者望而却步。在阅读图像处理方面的论文时,面对梯度、散度、黑塞矩阵、傅里叶变换等这些...笔者特别撰写了这本《图像处理中的数学修炼》,本文是该书中示例程序的源代码

    数字图像处理对数学的要求颇高,这不禁令很多学习者望而却步。在阅读图像处理方面的论文时,面对梯度、散度、黑塞矩阵、傅里叶变换等这些本该在微积分中早已耳熟能详的概念时,很多人仍然感觉一筹莫展。为了弭平图像处理道路上的数学险阻,帮助更多人学好数字图像处理,并更快地具备深入研究的能力。笔者特别撰写了这本《图像处理中的数学修炼》(该书现已由清华大学出版社正式出版)。欲了解《图像处理中的数学修炼》的更多详细内容,你可以参考本书的目录

    通常,我不喜欢翻开一本技术书,里面满篇满篇的都是代码。我也不希望用代码去凑页数或者挤占宝贵的篇幅。就《图像处理中的数学修炼》一书而言,更是如此。本书的重点在于全面系统地对图像处理中可能用到的各种数学基础加以总结归纳,所以数学原理才是我们所关注的重点!

    但是如果把数学原理同图像处理实践割裂开来,又可能令某些读者觉得“英雄无用武之地”!为了真正帮读者建立起从数学原理到图像处理实践的桥梁,本书特意在后半部分安排了一些比较实用且非常经典的图像处理算法介绍,而书籍的前半部分则是纯数学部分,后半部分中的经典算法大量使用了前半部分里的数学知识,我们希望以这种方式来帮助读者夯实基础、巩固所学。

    在后半部分的图像处理算法介绍部分,偶尔为了便于理解,本书配备了必要的MATLAB代码。但所用到的代码也非常有限的。因为这并不是一本教你怎么使用MATLAB的书!全书的代码不过六百多行,主要是为了对一些比较经典但又比较复杂的算法加以解释。这些“比较经典但又比较复杂的算法”主要包括(但不限于):

    • 基于暗通道的图像去雾实现
    • 对比度有限的自适应直方图均衡(CLAHE)
    • 自适应直方图均衡(AHE)
    • 基于小波变换的图像融合(失焦图像修复)
    • 基于泊松方程的泊松融合算法(基于迭代)
    • 基于泊松方程的泊松融合算法(有限差分方法解偏微分方程)
    • 基于主成分提取(PCA)的图像压缩

    特别感谢前期试读本书的读者给予笔者的意见反馈,以及CSND博客上【图像处理中的数学原理详解】专栏的读者提出的宝贵见解。下面所列之代码已经结合之前收到的意见反馈进行了调整和优化,并修正了此前存在的一些小问题。非常感谢这部分读者为提高本书质量所做之努力。此书文字部分的勘误可以参见图像处理中的数学修炼》一书之勘误表

    重要的事情说三遍:
    代码或者编程不是这本书的重点!
    代码或者编程不是这本书的重点!
    代码或者编程不是这本书的重点!

    所以全本书也就只有这么点代码。但如果你——本书的读者——对下面这些代码实现有疑问,或者发现那里有缺失,可以直接发邮件(邮件地址见博客左侧联系方式)给作者进行咨询或者获取补充代码。你也可以在“图像处理书籍读者群”中直接联系作者,提出你的疑问,或者得到你想得到的内容。面向本书读者的沟通渠道永远都是畅通的。


    P270

    i=double(imread('vase.tif'));
    [C,S]=wavedec2(i,2,'db1');
    a2=appcoef2(C,S,'db1',2);
    dh1=detcoef2('h',C,S,1);
    dv1=detcoef2('v',C,S,1);
    dd1=detcoef2('d',C,S,1);
    dh2=detcoef2('h',C,S,2);
    dv2=detcoef2('v',C,S,2);
    dd2=detcoef2('d',C,S,2);
    [x,y]=size(i);
    img = zeros(x,y);
    img(1:x/4,1:y/4) =im2uint8(mat2gray(a2));
    img(((x/4)+1):y/2,1:y/4) = im2uint8(mat2gray(dv2));
    img(((x/4)+1):x/2,1:y/4) = im2uint8(mat2gray(dv2));
    img(1:x/4,((y/4)+1):y/2) = im2uint8(mat2gray(dh2));
    img(((x/4)+1):x/2,((y/4)+1):y/2) = im2uint8(mat2gray(dd2));
    img(((x/2)+1):x,1:y/2) = im2uint8(mat2gray(dv1));
    img(1:x/2,((y/2)+1):y) = im2uint8(mat2gray(dh1));
    img(((x/2)+1):x,((y/2)+1):y) = im2uint8(mat2gray(dd1));
    imshow(img,[]);
    

    P272

    X1 = imread('cathe1.bmp');
    X2 = imread('cathe2.bmp');
    XFUS = wfusimg(X1,X2,'sym4',5,'mean','max');
    imshow(XFUS,[]);
    

    P273

    X1 = imread('cathe1.bmp');
    X2 = imread('cathe2.bmp');
    M1 = double(X1) / 256;
    M2 = double(X2) / 256;
    N = 4;
    wtype = 'sym4';
    [c0,s0] = wavedec2(M1, N, wtype);
    [c1,s1] = wavedec2(M2, N, wtype);
    length = size(c1);
    Coef_Fusion = zeros(1,length(2));
    %低频系数的处理,取平均值
    Coef_Fusion(1:s1(1,1)) = (c0(1:s1(1,1))+c1(1:s1(1,1)))/2;
    %处理高频系数,取绝对值大者,这里用到了矩阵乘法
    MM1 = c0(s1(1,1)+1:length(2));
    MM2 = c1(s1(1,1)+1:length(2));
    mm = (abs(MM1)) > (abs(MM2));
    Y  = (mm.*MM1) + ((~mm).*MM2);
    Coef_Fusion(s1(1,1)+1:length(2)) = Y;
    %重构
    Y = waverec2(Coef_Fusion,s0,wtype);
    imshow(Y,[]);
    

    P274

    I = imread('noise_lena.bmp');
    [thr,sorh,keepapp] = ddencmp('den','wv',I);
    de_I = wdencmp('gbl',I,'sym4',2,thr,sorh,keepapp);
    imwrite(im2uint8(mat2gray(de_I)), 'denoise_lena.bmp');
    

    P298

    I = imread('baboon.bmp');  
    I1 = double(I);  
    T = hadamard(8);  
    myFun1 = @(block_struct)T*block_struct.data*T/64;  
    H = blockproc(I1, [8 8], myFun1);  
    H(abs(H)<3.5)=0;  
    myFun2 = @(block_struct)T*block_struct.data*T;  
    I2 = blockproc(H, [8 8], myFun2);  
    subplot(121), imshow(I1,[]), title('original image');  
    subplot(122), imshow(I2,[]), title('zipped image');  
    

    P299

    I = imread('baboon.bmp');  
    I1 = double(I);  
    [m n] =size(I);  
    sizi = 8;  
    num = 16;  
    %分块进行离散沃尔什变换  
    T = hadamard(sizi);  
    myFun1 = @(block_struct)T*block_struct.data*T/(sizi.^2);  
    hdcoe = blockproc(I1, [sizi, sizi], myFun1);  
    %重新排列系数  
    coe = im2col(hdcoe,  [sizi, sizi], 'distinct');  
    coe_t = abs(coe);  
    [Y, ind] = sort(coe_t);  
    %舍去绝对值较小的系数  
    [m_c, n_c] = size(coe);  
    for i = 1:n_c  
    coe(ind(1:num, i), i)=0;  
    end  
    %重建图像  
    re_hdcoe = col2im(coe, [sizi, sizi], [m, n], 'distinct');  
    myFun2 = @(block_struct)T*block_struct.data*T;  
    re_s = blockproc(re_hdcoe, [sizi, sizi], myFun2);  
    subplot(121), imshow(I1,[]), title('original image');  
    subplot(122), imshow(re_s,[]), title('compressed image');  
    

    P307

    I = imread('baboon.bmp');  
    x = double(I)/255;  
    [m,n]=size(x);  
    y =[];  
    %拆解图像  
    for i = 1:m/8;  
        for j = 1:n/8;  
            ii = (i-1)*8+1;  
            jj = (j-1)*8+1;  
            y_app = reshape(x(ii:ii+7,jj:jj+7),1,64);  
            y=[y;y_app];  
        end  
    end  
      
    %KL变换  
    [COEFF,SCORE,latent] = princomp(y);  
    kl = y * COEFF;  
      
    kl1 = kl;  
    kl2 = kl;  
    kl3 = kl;  
      
    %置零压缩过程  
    kl1(:, 33:64)=0;  
    kl2(:, 17:64)=0;  
    kl3(:, 9:64)=0;  
      
    %KL逆变换  
    kl_i = kl*COEFF';  
    kl1_i = kl1*COEFF';  
    kl2_i = kl2*COEFF';  
    kl3_i = kl3*COEFF';  
      
    image = ones(256,256);  
    image1 = ones(256,256);  
    image2 = ones(256,256);  
    image3 = ones(256,256);  
      
    k=1;  
    %重组图像  
    for i = 1:m/8;  
        for j = 1:n/8;  
      
            y = reshape(kl_i(k, 1:64),8,8);  
            y1 = reshape(kl1_i(k, 1:64),8,8);  
            y2 = reshape(kl2_i(k, 1:64),8,8);  
            y3 = reshape(kl3_i(k, 1:64),8,8);  
      
            ii = (i-1)*8+1;  
            jj = (j-1)*8+1;  
      
            image(ii:ii+7,jj:jj+7) = y;  
            image1(ii:ii+7,jj:jj+7) = y1;  
            image2(ii:ii+7,jj:jj+7) = y2;  
            image3(ii:ii+7,jj:jj+7) = y3;  
      
            k=k+1;  
        end  
    end  
    

    ##P356-1

    mountains = double(imread('./img/mountain.jpg'));
    moon = double(imread('./img/moon.png'));
    sizeSrc = size(mountains);
    sizeDst = size(moon);
    
    gradient_inner = moon(1:sizeDst(1)-2,2:sizeDst(2)-1,:)...
        + moon(3:sizeDst(1),2:sizeDst(2)-1,:)...
        + moon(2:sizeDst(1)-1,1:sizeDst(2)-2,:)...
        + moon(2:sizeDst(1)-1,3:sizeDst(2),:)...
        - 4*moon(2:sizeDst(1)-1,2:sizeDst(2)-1,:);
    

    P356-2

    Lap = [0, 1, 0;1, -4, 1;0, 1, 0];
    
    I1 = conv2(double(moon(:,:,1)), double(Lap));
    I2 = conv2(double(moon(:,:,2)), double(Lap));
    I3 = conv2(double(moon(:,:,3)), double(Lap));
    gradient_inner(:, :, 1) = I1(3:sizeDst(1),3:sizeDst(2));
    gradient_inner(:, :, 2) = I2(3:sizeDst(1),3:sizeDst(2));
    gradient_inner(:, :, 3) = I3(3:sizeDst(1),3:sizeDst(2));
    

    P357

    dstX = 350;dstY = 100;
    rebuilt = mountains(dstY:dstY+sizeDst(1)-1,dstX:dstX+sizeDst(2)-1,:);
    
    for n = [1:1000]
        rebuilt(2:2:sizeDst(1)-1,2:2:sizeDst(2)-1,:)= ...
            (rebuilt(1:2:sizeDst(1)-2 , 2:2:sizeDst(2)-1,:)...
            +rebuilt(3:2:sizeDst(1) , 2:2:sizeDst(2)-1,:)...
            +rebuilt(2:2:sizeDst(1)-1 , 1:2:sizeDst(2)-2,:)...
            +rebuilt(2:2:sizeDst(1)-1 , 3:2:sizeDst(2),:)...
            -gradient_inner(1:2:sizeDst(1)-2 , 1:2:sizeDst(2)-2,:))/4;
         rebuilt(3:2:sizeDst(1)-1,3:2:sizeDst(2)-1,:)= ...
            (rebuilt(2:2:sizeDst(1)-2 , 3:2:sizeDst(2)-1,:)...
            +rebuilt(4:2:sizeDst(1) , 3:2:sizeDst(2)-1,:)...
            +rebuilt(3:2:sizeDst(1)-1 , 2:2:sizeDst(2)-2,:)...
            +rebuilt(3:2:sizeDst(1)-1 , 4:2:sizeDst(2),:)...
            -gradient_inner(2:2:sizeDst(1)-2 , 2:2:sizeDst(2)-2,:))/4;
         rebuilt(3:2:sizeDst(1)-1,2:2:sizeDst(2)-1,:)= ...
            (rebuilt(2:2:sizeDst(1)-2 , 2:2:sizeDst(2)-1,:)...
            +rebuilt(4:2:sizeDst(1) , 2:2:sizeDst(2)-1,:)...
            +rebuilt(3:2:sizeDst(1)-1 , 1:2:sizeDst(2)-2,:)...
            +rebuilt(3:2:sizeDst(1)-1 , 3:2:sizeDst(2),:)...
            -gradient_inner(2:2:sizeDst(1)-2 , 1:2:sizeDst(2)-2,:))/4;
        rebuilt(2:2:sizeDst(1)-1 , 3:2:sizeDst(2)-1,:)= ...
            (rebuilt(1:2:sizeDst(1)-2 , 3:2:sizeDst(2)-1,:)...
            +rebuilt(3:2:sizeDst(1) , 3:2:sizeDst(2)-1,:)...
            +rebuilt(2:2:sizeDst(1)-1 , 2:2:sizeDst(2)-2,:)...
            +rebuilt(2:2:sizeDst(1)-1 , 4:2:sizeDst(2),:)...
            -gradient_inner(1:2:sizeDst(1)-2 , 2:2:sizeDst(2)-2,:))/4;
    end
    
    mountains(dstY:sizeDst(1)+dstY-1,dstX:sizeDst(2)+dstX-1,:) = rebuilt;
    figure,imshow(uint8(mountains));
    

    P360-P361

    TargetImg   = imread('pool-target.jpg');  
    SourceImg   = imread('bear.jpg');  
    SourceMask  = im2bw(imread('bear-mask.jpg'));  
    
    [SrcBoundry, ~] = bwboundaries(SourceMask, 8);
    figure, imshow(SourceImg), axis image  
    hold on  
    for k = 1:length(SrcBoundry)  
        boundary = SrcBoundry{k};  
        plot(boundary(:,2), boundary(:,1), 'r', 'LineWidth', 2)  
    end  
    title('Source image intended area for cutting from');
    
    position_in_target = [10, 225];%xy
    [TargetRows, TargetCols, ~] = size(TargetImg);
    [row, col] = find(SourceMask);
    start_pos = [min(col), min(row)];
    end_pos  = [max(col), max(row)];
    frame_size = end_pos - start_pos;
    
    if (frame_size(1) + position_in_target(1) > TargetCols)
        position_in_target(1) = TargetCols - frame_size(1);
    end
    
    if (frame_size(2) + position_in_target(2) > TargetRows)
        position_in_target(2) = TargetRows - frame_size(2);
    end
    
    MaskTarget = zeros(TargetRows, TargetCols);
    MaskTarget(sub2ind([TargetRows, TargetCols], row-start_pos(2)+ ...
    position_in_target(2), col-start_pos(1)+position_in_target(1))) = 1;
    
    TargBoundry = bwboundaries(MaskTarget, 8);
    figure, imshow(TargetImg), axis image
    hold on
    for k = 1:length(TargBoundry)
        boundary = TargBoundry{k};
        plot(boundary(:,2), boundary(:,1), 'r', 'LineWidth', 1)
    end
    

    P362

    templt = [0 -1 0; -1 4 -1; 0 -1 0];  
    LaplacianSource = imfilter(double(SourceImg), templt, 'replicate');  
    VR = LaplacianSource(:, :, 1);  
    VG = LaplacianSource(:, :, 2);  
    VB = LaplacianSource(:, :, 3);
    
    TargetImgR = double(TargetImg(:, :, 1));  
    TargetImgG = double(TargetImg(:, :, 2));  
    TargetImgB = double(TargetImg(:, :, 3));  
      
    TargetImgR(logical(MaskTarget(:))) = VR(SourceMask(:));  
    TargetImgG(logical(MaskTarget(:))) = VG(SourceMask(:));  
    TargetImgB(logical(MaskTarget(:))) = VB(SourceMask(:));  
      
    TargetImgNew = cat(3, TargetImgR, TargetImgG, TargetImgB);  
    figure, imagesc(uint8(TargetImgNew)), axis image;
    
    AdjacencyMat = calcAdjancency(MaskTarget);
    
    ResultImgR=PoissonSolver(TargetImgR,MaskTarget,AdjacencyMat,TargBoundry);
    ResultImgG=PoissonSolver(TargetImgG,MaskTarget,AdjacencyMat,TargBoundry);
    ResultImgB=PoissonSolver(TargetImgB,MaskTarget,AdjacencyMat,TargBoundry);
    
    ResultImg = cat(3, ResultImgR, ResultImgG, ResultImgB);
    
    %% Show the final results
    figure;
    imshow(uint8(ResultImg));
    

    特别说明:函数calcAdjancency和PoissonSolver的实现请在图像处理学习群中直接联系群主获取,群号见文末。


    P393

    image = imread('Unequalized_Hawkes_Bay_NZ.jpg');  
    Img = rgb2gray(image);  
    [height,width]=size(Img);
    
    NumPixel = zeros(1,256);%统计各灰度数目,共256个灰度级
    for i = 1:height  
        for j = 1: width  
        %对应灰度值像素点数量增加一
        %因为NumPixel的下标是从1开始,但是图像像素的取值范围是0~255,
        %所以用NumPixel(Img(i,j) + 1)  
        NumPixel(Img(i,j) + 1) = NumPixel(Img(i,j) + 1) + 1;  
        end  
    end  
    
    ProbPixel = zeros(1,256);
    for i = 1:256  
        ProbPixel(i) = NumPixel(i) / (height * width * 1.0);
    end 
    
    CumuPixel = cumsum(ProbPixel);  
    CumuPixel = uint8(255 .* CumuPixel + 0.5);  
    
    for i = 1:height  
        for j = 1: width  
            Img(i,j) = CumuPixel(Img(i,j));  
        end  
    end
    
    imshow(Img)
    

    P395-1

    a = imread('couple.tiff');
    R = a(:,:,1);
    G = a(:,:,2);
    B = a(:,:,3);
          
    R = histeq(R, 256);
    G = histeq(G, 256);
    B = histeq(B, 256);
          
    a(:,:,1) = R;
    a(:,:,2) = G;
    a(:,:,3) = B;
    imshow(a)
    

    P395-2

    Img = imread('couple.tiff');
    hsvImg = rgb2hsv(Img);
    V = hsvImg(:,:,3);
    [height,width] = size(V);
    
    V = uint8(V*255);
    NumPixel = zeros(1,256);
    for i = 1:height
        for j = 1: width
            NumPixel(V(i,j) + 1) = NumPixel(V(i,j) + 1) + 1;
        end  
    end
    
    ProbPixel = zeros(1,256);
    for i = 1:256
        ProbPixel(i) = NumPixel(i) / (height * width * 1.0);
    end
    
    CumuPixel = cumsum(ProbPixel);
    CumuPixel = uint8(255 .* CumuPixel + 0.5);
      
    for i = 1:height  
        for j = 1: width  
            if V(i,j)==0
    			V(i,j) = CumuPixel(V(i,j)+1);
    		else 
    			V(i,j) = CumuPixel(V(i,j));
    		end 
        end  
    end  
       
    V = im2double(V);
    hsvImg(:,:,3) = V;
    outputImg = hsv2rgb(hsvImg);
    imshow(outputImg);
    

    P397

    img = imread('space.jpg');
    rimg = img(:,:,1);
    gimg = img(:,:,2);
    bimg = img(:,:,3);
    resultr = adapthisteq(rimg);
    resultg = adapthisteq(gimg);
    resultb = adapthisteq(bimg);
    result = cat(3, resultr, resultg, resultb);
    imshow(result);
    

    P398-1

    clear;  
    img = imread('space.jpg');  
    cform2lab = makecform('srgb2lab');  
    LAB = applycform(img, cform2lab);  
    L = LAB(:,:,1);  
    LAB(:,:,1) = adapthisteq(L);  
    cform2srgb = makecform('lab2srgb');  
    J = applycform(LAB, cform2srgb);  
    imshow(J);  
    

    P398-2

    clc;
    clear all;
    Img = rgb2gray(imread('space.jpg'));
    [h,w] = size(Img);  
    minV = double(min(min(Img)));
    maxV = double(max(max(Img)));
    imshow(Img);
    

    P399

    NrX = 8;
    NrY = 4;
    HSize = ceil(h/NrY);
    WSize = ceil(w/NrX);
          
    deltay = NrY*HSize - h;  
    deltax = NrX*WSize - w;  
          
    tmpImg = zeros(h+deltay,w+deltax);  
    tmpImg(1:h,1:w) = Img;  
    
    new_w = w + deltax;
    new_h = h + deltay;
    NrPixels = WSize * WSize;
    
    % NrBins - Number of greybins for histogram ("dynamic range")
    NrBins = 256;
    
    LUT = zeros(maxV+1,1);
    
    for i=minV:maxV  
        LUT(i+1) = fix(i - minV);%i+1
    end  
    
    Bin = zeros(new_h, new_w);  
    for m = 1 : new_h  
        for n = 1 : new_w  
            Bin(m,n) = 1 + LUT(tmpImg(m,n) + 1);
        end  
    end  
    
    Hist = zeros(NrY, NrX, 256);
    for i=1:NrY  
        for j=1:NrX  
            tmp = uint8(Bin(1+(i-1)*HSize:i*HSize, 1+(j-1)*WSize:j*WSize));
            %tmp = tmpImg(1+(i-1)*HSize:i*HSize,1+(j-1)*WSize:j*WSize);
            [Hist(i, j, :), x] = imhist(tmp, 256);  
        end  
    end
    
    Hist = circshift(Hist,[0, 0, -1]);
    
    ClipLimit = 2.5;  
    ClipLimit = max(1,ClipLimit * HSize * WSize/NrBins);
    Hist = clipHistogram(Hist,NrBins,ClipLimit,NrY,NrX);
    Map=mapHistogram(Hist, minV, maxV, NrBins, NrPixels, NrY, NrX);
    
    yI = 1;  
    for i = 1:NrY+1  
        if i == 1  
            subY = floor(HSize/2);
            yU = 1;
            yB = 1;
        elseif i == NrY+1  
            subY = floor(HSize/2);
            yU = NrY;
            yB = NrY;
        else
            subY = HSize;
            yU = i - 1;
            yB = i;
        end
        xI = 1;
        for j = 1:NrX+1
            if j == 1  
                subX = floor(WSize/2);
                xL = 1;
                xR = 1;
            elseif j == NrX+1
                subX = floor(WSize/2);
                xL = NrX;
                xR = NrX;
            else
                subX = WSize;
                xL = j - 1;
                xR = j;
            end
            UL = Map(yU,xL,:);
            UR = Map(yU,xR,:);
            BL = Map(yB,xL,:);
            BR = Map(yB,xR,:);
            subImage = Bin(yI:yI+subY-1,xI:xI+subX-1);  
    
            %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
            sImage = zeros(size(subImage));
            num = subY * subX;
            for i = 0:subY - 1
                inverseI = subY - i;
                for j = 0:subX - 1
                    inverseJ = subX - j;
                    val = subImage(i+1,j+1);
                    sImage(i+1, j+1)=(inverseI*(inverseJ*UL(val)+j*UR(val))...
                                       + i*(inverseJ*BL(val)+j*BR(val)))/num;
                end
            end
            %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    
            output(yI:yI+subY-1, xI:xI+subX-1) = sImage;
            xI = xI + subX;
        end
        yI = yI + subY;
    end  
    
    output = output(1:h, 1:w);
    figure, imshow(output, []);
    

    P404

    img = rgb2gray(imread('theatre.jpg'));
    img_ref = rgb2gray(imread('rpic.jpg'));
    [hgram, x] = imhist(img_ref);
    J = histeq(img, hgram);
    subplot(2,3,1), imshow(img), title('original image');
    subplot(2,3,4), imhist(img), title('original image');
    subplot(2,3,2), imshow(img_ref), title('reference image');
    subplot(2,3,5), imhist(img_ref), title('reference image');
    subplot(2,3,3), imshow(J), title('output image');
    subplot(2,3,6), imhist(J), title('output image');
    

    P409

    %求一幅图像的暗通道图,窗口大小为15*15
    imageRGB = imread('picture.bmp');
    imageRGB = double(imageRGB);
    imageRGB = imageRGB./255;
    dark = darkChannel(imageRGB);
    
    % 选取暗通道图中最亮的0.1%像素,从而求得大气光
    [m, n, ~] = size(imageRGB);
    imsize = m * n;
    numpx = floor(imsize/1000);
    JDarkVec = reshape(dark,imsize,1);
    ImVec = reshape(imageRGB,imsize,3);
    
    [JDarkVec, indices] = sort(JDarkVec);
    indices = indices(imsize-numpx+1:end);
    
    atmSum = zeros(1,3);
    for ind = 1:numpx
        atmSum = atmSum + ImVec(indices(ind),:);
    end
    
    atmospheric = atmSum / numpx;
    
    %求解透射率,并通过omega参数来选择保留一定程度的雾霾,以免损坏真实感
    omega = 0.95; 
    im = zeros(size(imageRGB));
    
    for ind = 1:3 
        im(:,:,ind) = imageRGB(:,:,ind)./atmospheric(ind);
    end
    
    dark_2 = darkChannel(im);
    t = 1-omega*dark_2;
    
    %通过导向滤波来获得更为精细的透射图
    r = 60;
    eps = 10^-6;
    refined_t = guidedfilter_color(imageRGB, t, r, eps);
    refinedRadiance = getRadiance(atmospheric, imageRGB, refined_t);
    

    P410

    function dark = darkChannel(imRGB)
    
    r=imRGB(:,:,1);
    g=imRGB(:,:,2);
    b=imRGB(:,:,3);
    
    [m n] = size(r);
    a = zeros(m,n);
    for i = 1: m     
        for j = 1: n
             a(i,j) = min(r(i,j), g(i,j));
             a(i,j)= min(a(i,j), b(i,j));
        end
    end
    
    d = ones(15,15);
    fun = @(block_struct)min(min(block_struct.data))*d;
    dark = blockproc(a, [15 15], fun); 
    
    dark = dark(1:m, 1:n);
    

    本书源起

    数字图像处理对数学的要求颇高,这不禁令很多学习者望而却步。在阅读图像处理方面的论文时,面对梯度、散度、黑塞矩阵、傅里叶变换等这些本该在微积分中早已耳熟能详的概念时,很多人仍然感觉一筹莫展。

    大约三年前,我开始在博客上介绍一些数字图像处理中的数学基础和数学原理,并专门开设了一个“图像处理中的数学原理”专栏,其中大概收录了三十几篇文章。很多人开始留言询问我,有没有这样一本书?彼时我并没有将该系列文章付梓的想法。但是耐不住众多热情的读者不断敦促我将这个系列相对完整和系统地整理成一本可读性更强的书籍。于是便有了这本书——《图像处理中的数学修炼》。

    大约一年前清华出版社的编辑同我联系,我想或许时机已到,遂开始着手将千头万绪已经发布的和未曾发布的资料整理成书。期间为了能够更好地呈现这本书,出版日期也是一拖再拖。从最初的十一,到双十一,再到春节前,直到现在的烟花三月。这本《图像处理中的数学修炼》可真算是“千呼万唤始出来”。期间很多热情的读者三番五次地问询该书的出版进度,着实令我感觉身上压力不小。无奈好事毕竟多磨,所幸终于瓜熟蒂落。现在这本书终于同大家见面了!


    1496307488_2945.png
    展开全文
  • 目录 ...初学OpenCV图像处理伙伴肯定对什么高斯函数、滤波处理、阈值二值化等特性非常头疼,这里给各位分享一个项目,可通过摄像头实时动态查看各类图像处理的特点,也可对各位调参、测试...

    目录

    1、导入库文件

    2、设计GUI

    3、调用摄像头

    4、实时图像处理

    4.1、阈值二值化

    4.2、边缘检测

    4.3、轮廓检测

    4.4、高斯滤波

    4.5、色彩转换

    4.6、调节对比度

    5、退出系统


    初学OpenCV图像处理的小伙伴肯定对什么高斯函数、滤波处理、阈值二值化等特性非常头疼,这里给各位分享一个小项目,可通过摄像头实时动态查看各类图像处理的特点,也可对各位调参、测试有一定帮助,项目演示效果如下:

    1、导入库文件

    这里主要使用PySimpleGUI、cv2和numpy库文件,PySimpleGUI库文件实现GUI可视化,cv2库文件是Python的OpenCV接口文件,numpy库文件实现数值的转换和运算,均可通过pip导入。

    import PySimpleGUI as sg  #pip install pysimplegui
    import cv2  #pip install opencv-python
    import numpy as np #pip install numpy

    2、设计GUI

    基于PySimpleGUI库文件实现GUI设计,本项目界面设计较为简单,设计800X400尺寸大小的框图,浅绿色背景,主要由摄像头界面区域和控制按钮区域两部分组成。效果如下所示:

    GUI代码如下所示:

        #背景色
        sg.theme('LightGreen')
    
        #定义窗口布局
        layout = [
          [sg.Image(filename='', key='image')],
          [sg.Radio('None', 'Radio', True, size=(10, 1))],
          [sg.Radio('threshold', 'Radio', size=(10, 1), key='thresh'),
           sg.Slider((0, 255), 128, 1, orientation='h', size=(40, 15), key='thresh_slider')],
          [sg.Radio('canny', 'Radio', size=(10, 1), key='canny'),
           sg.Slider((0, 255), 128, 1, orientation='h', size=(20, 15), key='canny_slider_a'),
           sg.Slider((0, 255), 128, 1, orientation='h', size=(20, 15), key='canny_slider_b')],
          [sg.Radio('contour', 'Radio', size=(10, 1), key='contour'),
           sg.Slider((0, 255), 128, 1, orientation='h', size=(20, 15), key='contour_slider'),
           sg.Slider((0, 255), 80, 1, orientation='h', size=(20, 15), key='base_slider')],
          [sg.Radio('blur', 'Radio', size=(10, 1), key='blur'),
           sg.Slider((1, 11), 1, 1, orientation='h', size=(40, 15), key='blur_slider')],
          [sg.Radio('hue', 'Radio', size=(10, 1), key='hue'),
           sg.Slider((0, 225), 0, 1, orientation='h', size=(40, 15), key='hue_slider')],
          [sg.Radio('enhance', 'Radio', size=(10, 1), key='enhance'),
           sg.Slider((1, 255), 128, 1, orientation='h', size=(40, 15), key='enhance_slider')],
          [sg.Button('Exit', size=(10, 1))]
        ]
    
        #窗口设计
        window = sg.Window('OpenCV实时图像处理',
                   layout,
                   location=(800, 400),
                   finalize=True)

    3、调用摄像头

    打开电脑内置摄像头,将数据显示在GUI界面上,效果如下所示:

    代码如下所示:

        #打开内置摄像头
        cap = cv2.VideoCapture(0)
        while True:
            event, values = window.read(timeout=0, timeout_key='timeout')
    
            #实时读取图像
            ret, frame = cap.read()
    
            #GUI实时更新
            imgbytes = cv2.imencode('.png', frame)[1].tobytes()
            window['image'].update(data=imgbytes)
    
        window.close()

    4、实时图像处理

    4.1、阈值二值化

    进行阈值二值化操作,大于阈值values['thresh_slider']的,使用255表示,小于阈值values['thresh_slider']的,使用0表示,效果如下所示:

     代码如下所示:

    if values['thresh']:
        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2LAB)[:, :, 0]
        frame = cv2.threshold(frame, values['thresh_slider'], 255, cv2.THRESH_BINARY)[1]

    4.2、边缘检测

    进行边缘检测,values['canny_slider_a']表示最小阈值,values['canny_slider_b']表示最大阈值,效果如下所示:

    代码如下所示:

    if values['canny']:
        frame = cv2.Canny(frame, values['canny_slider_a'], values['canny_slider_b'])

    4.3、轮廓检测

    轮廓检测是形状分析和物体检测和识别的有用工具,连接所有连续点(沿着边界)的曲线,具有相同的颜色或强度,效果如下所示:

     代码如下所示:

    if values['contour']:
        hue = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
        hue = cv2.GaussianBlur(hue, (21, 21), 1)
        hue = cv2.inRange(hue, np.array([values['contour_slider'], values['base_slider'], 40]),
                          np.array([values['contour_slider'] + 30, 255, 220]))
        cnts= cv2.findContours(hue, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[0]
        cv2.drawContours(frame, cnts, -1, (0, 0, 255), 2)
    

    4.4、高斯滤波

    进行高斯滤波,(21, 21)表示高斯矩阵的长与宽都是21,标准差取values['blur_slider'],效果如下所示:

     代码如下所示:

    if values['blur']:
        frame = cv2.GaussianBlur(frame, (21, 21), values['blur_slider'])
    

    4.5、色彩转换

    色彩空间的转化,HSV转换为BGR,效果如下所示:

     代码如下所示:

    if values['hue']:
        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
        frame[:, :, 0] += int(values['hue_slider'])
        frame = cv2.cvtColor(frame, cv2.COLOR_HSV2BGR)

    4.6、调节对比度

    增强对比度,使图像中的细节看起来更加清晰,效果如下所示:

      代码如下所示:

    if values['enhance']:
        enh_val = values['enhance_slider'] / 40
        clahe = cv2.createCLAHE(clipLimit=enh_val, tileGridSize=(8, 8))
        lab = cv2.cvtColor(frame, cv2.COLOR_BGR2LAB)
        lab[:, :, 0] = clahe.apply(lab[:, :, 0])
        frame = cv2.cvtColor(lab, cv2.COLOR_LAB2BGR)
    

    5、退出系统

    直接break即可跳出循环。

    if event == 'Exit' or event is None:
        break

    拓展学习:基于Python的人工智能美颜系统 

    请关注公众号,回复关键字:OpenCV实时图像处理,获取项目资源。

    展开全文
  • 原文地址:波变换在图像处理中的应用作者:茉莉清茶波变换在图像处理中的应用 一 波与图像去噪   图像在采集,转换和传输过程中常常受到成像设备和外部环境噪声干扰等影响产生噪声。波去噪是利用波变换中...

    小波变换在图像处理中的应用

    小波与图像去噪

       图像在采集,转换和传输过程中常常受到成像设备和外部环境噪声干扰等影响产生噪声。小波去噪是利用小波变换中的变尺度特性对确定信号具有一种“集中”的能力,当图像信号的能量集中于少数小波系数上,那么这些系数的值必定大于能量分散的大量噪声小波系数值。只要选取适当的阈值,舍去绝对值小于阈值的小波系数,就可实现图像的降噪。

    小波与图像压缩

       小波变换最成功的图像处理应用领域之一就是图像压缩。小波变换将强相关的空间像素阵影射成完全不相关的,能量分布紧凑的小波系数阵,占少数的大的小波系数代表了图像中最主要的能量成分,占多数的小的小波系数表示了一些不重要的细节分量,通过量化去除小系数多代表的细节分量,用很少的码子来描述大系数所代表的主要能量成分,从而达到高的压缩比。小波图像压缩的研究表明,现代应用所需要的许多特征如多分辨,多层质量控制,嵌入式码流等与小波图像编码结构非常自然地融合在一起,在较大压缩比下,小波图像压缩重构质量明显优于DCT变换的方法。因此,在新一代静止图像压缩标准JPEC2000中,采用小波图像编码作为核心算法。

    小波与图像分割

        图像分割是计算机视觉和图像理解的最基本问题,分割结果决定图像处理系统高层模块的性能。图像分割按照一定准则把图像划分为若干互不相交的区域,别分割的区域应满足同质性和唯一性。
        由于边缘上图像的灰度级不连续,具有奇异性。基于小波变换的边缘检测进行图像分割,即利用小波系数的多分辨率特征,利用小波分析的局部化特性,获得不同尺度下领域特征。根据这些小波特征可以进行模式分类,图像分割。另外,利用小波分解后的高频信息,还可以进行多尺度边缘检测。

        目前,基于小波分析的图像分割与边缘检测可以分为两大类:一类是基于滤波器尺度的多尺度图像分割方法;或是直接构造边缘算子作用于原图像函数以检测边缘;或是先通过小波变换获得图像地多尺度特征,然后对像素进行分类和分割。另一种是构造基于像素点外的尺寸及灰度级差的多尺度函数,并以此函数构造边缘映射。这种方法集成了边界和区域处的特征信息,具有潜在的研究价值。

    小波变换在图像融合中的应用

    这里以两幅图像的融合为例,多幅图像的融合方法可依此类推。基于小波变换的融合算法的流程阐述如下:首先,对已配准的源图像进行小波分解,相当于使用一组高低通滤波器进行滤波,分离出高频信息和低频信息;其次,对每层分解得到的高频信息和低频信息依据所得到的信息特点,采取不同的融合策略,在各自的变换域进行特征信息抽取,分别进行融合;最后,采用第一步的小波变换的重构算法对处理后的小波系数进行反变换重建图像,即可得到融合图像[7]

    Mallat 提出了小波变换的分解与重构的快速算法。对一维信号f(x),分解公式为:

     

    为分辨率 下的尺度函数, 为分辨率 下的小波函数。 、 分别为逼近系数和细节系数。

    小波变换利用Mallat提出的小波多分辨率分析思想及小波的分解和重构快速算法进行图像融合。用小波变换可以将图像分解为更低分辨率水平上的低频轮廓信息和原始信号在水平、垂直和对角线方向的高频细节信息,且可以对图像作多次分解,形成多级子带信号。小波运算往往通过小波分解后小波系数的替换、选择、权值或叠加运算进行融合,运算的规则由小波系数的大小、统计值或基于小波变换特性定义的新判决量来确定。从目前融合效果上看,小波变换是一种复杂但融合效果较好的算法,也是一种很有前途的算法[8]

    对待融合图像进行多层小波分解,得吐血的低频分量和图像的高频分量,然后分别对低频分量和高频分量采取相应的任何算子和融合规则进行融合处理,得到融合图像的低频分量和高频分量,然后进行小波逆运算得到融合后的图像,融合原理图如下图所示:

    图像A

     

    小波变换系数A

     

     

     

    融合后 图  像

    融   合

     

    规   则

    小波变换系数B

    图像B

    融合后小波系数

     

     

     

     

     


    图1 小波变换图像融合流程示意图

     

        该系统的执行步骤如下:

        (1) 根据Mallat 算法对原始图像进行小波分解, 得到其小波变换系数。

        (2) 由原始图像的低频图像根据一定的融合准则, 确定融合图像的逼近图像。

        (3) 对高频系数应用Cross- band- window算法, 确定融合图像的高频系数。

        (4) 对融合后的系数进行逆小波变换, 获得融合后的图像。

    由于变换后的低频系数和高频系数分别表示不同的图像特征, 因此, 一般采用不同的融合方法。低频系数表示图像的近似信息, 一般求初始图像的平均, 或者把初始图像之一的低频系数直接作为融合图像的低频分量。

    例1  基于小波变换图像融合程序及结果分析

    imgPan = imread('D:work3.jpg');

    imgMul = imread('D:work4.jpg');

    subplot(1,3,1), imshow(imgMul), xlabel ('(a)高分辨率多光谱影像');

    subplot(1,3,2), imshow(imgPan), xlabel ('(b)多光谱影像');

    mulR = imgMul (:,:,1);

    mulG = imgMul (:,:,2);

    mulB = imgMul (:,:,3);

    [Cpan,Lpan] = wavedec2(imgPan,3,'db13');

    imgWH = Lpan(1,:);

    length = imgWH(1)*imgWH(2);

    [Ctmr,Ltmr] = wavedec2(imgR,3,' db13' );

    Cr = Cpan; Cr(1:length) = Ctmr(1:length);

    [Ctmg,Ltmg] = wavedec2(imgG,3,' db13' );

    Cg = Cpan; Cg(1:length) = Ctmg(1:length);

    [Ctmb,Ltmb] = wavedec2(imgB,3,' db13' );

    Cb = Cpan; Cb(1:length) = Ctmb(1:length);

    imgResult(:,:,1) = waverec2(Cr,Lpan,' db13' );

    imgResult(:,:,2) = waverec2(Cg,Lpan,' db13' );

    imgResult(:,:,3) = waverec2(Cb,Lpan,' db13' );

    imwrite(uint8(imgResult), ' Merge.bmp' );

    subplot(1,3,3), imshow(uint8(imgResult), xlabel (' (c)小波融合图像' );

     

    图1 高分辨率影像

     

    图2 多光谱影像

     

    图3 小波变换后影像

    与传统的图像融合方法如HIS等相比, 小波融合模型不仅能够针对输入图像的不同特征来合理选择小波变换的次数, 而且在融合操作时又可以根据实际需要来引入双方的细节信息, 从而表现出更强的针对性和实用性, 融合效果更好。另外, 从实施过程的灵活性方面评价, HIS 变换只能而且必须同时对三个波段进行融合操作, 小波方法能够完成对单一波段或多个波段的融合运算。

    例2  基于小波变换图像复原程序结果及分析

    %下面装入原始图像,X中含有被装载的图像

    load facets;

    %画出原始图像

    subplot(221);image(X);colormap(map);

    title('原始图像');

    axis square

    %产生含噪声图像

    init=2055615866;randn('seed',init)

    x=X+10*randn(size(X));

    %画出含噪声图像

    subplot(222);image(X);colormap(map);

    title('含噪声图像');

    axis square

    %下面进行图像的去噪处理

    %用小波画数coif3对x进行2层小波分解

    [c,s]=wavedec2(x,2,'coif3');

    %提取小波分解中第一层的低频图像,即实现了低通滤波去噪

    %设置尺度向量n

    n=[1,2]

    p=[10.12,23.28];

    %对三个方向高频系数进行阈值处理

    nc=wthcoef2('h',c,s,n,p,'s');

    nc=wthcoef2('v',c,s,n,p,'s');

    nc=wthcoef2('d',c,s,n,p,'s');

    %对新的小波分解结构[nc,s]进行重构

    xx=waverec2(nc,s,'coif3');

    %画出重构后图像的波形

    subplot(223);image(X);colormap(map);

    title('去噪后的图像');

    axis square;

        原始图像             含噪声图像             去噪后图像

                

    图4 去噪例三

    二维信号在应用中一般表现为图像信号,二维信号在小波域中的降噪方法的基本思想与一维情况一样,在阈值选择上,可以使用统一的全局阈值,有可以分作三个方向,分别是水平方向、竖直方向和对角方向,这样就可以把在所有方向的噪声分离出来,通过作用阈值抑制其成分。

                                                                        

     

    展开全文
  • 该系列文章是讲解Python OpenCV图像处理知识,前期主要讲解图像入门、OpenCV基础用法,中期讲解图像处理的各种算法,包括图像锐化算子、图像增强技术、图像分割等,后期结合深度学习研究图像识别、图像分类应用。...
  • 由清华大学出版社出版的《图像处理中的数学修炼》这本书是今年3月左右正式上市销售的。现在三个多月过去了,已经积累了大量的读者。但是,随着读者数量的增加,近来有部分读者在跟我交流和咨询的时候表现出来许多在...
  • Python图像处理

    2018-03-03 22:27:15
    第 1 章 基本的图像操作和处理本章讲解操作和处理图像的基础知识,将通过大量...1.1 PIL:Python图像处理类库PIL(Python Imaging Library Python,图像处理类库)提供了通用的图像处理功能,以及大量有用的基本图...
  •  这篇文章的主要目的是通过建立一维傅里叶变换与图像傅里叶变换中相关概念的对应关系来帮助读者理解图像处理中的离散傅里叶变换,因此,理解图像中离散傅里叶变换的前提条件是读者需要了解一维傅里叶变换的基本知识...
  • 航天和航空技术方面的应用数字图像处理技术在航天和航空技术方面的应用,除了JPL对月球、火星照片的处理之外,另一方面的应用是在飞机遥感和卫星遥感技术。许多国家每天派出很多侦察飞机对地球上有兴趣的地...
  • 波变换图像处理

    2015-11-15 13:04:30
    应用波变换对图像处理 图像金字塔,每一层的像素数为(2^i,2^j):图像金字塔基本操作 对一张图像不断的模糊之后向下采样,得到不同分辨率的图像,同时每次得到的 新的图像宽与高是原来图像的1/2,...
  • 用函数对cameraman图像进行非线性变换 a=imread(‘F:\work\Digital Image Processing\2015\ketangshiyan\ceshitu\cameraman.jpg’) ; %读取原始图像 figure(1); imshow(a); xlabel(‘(a)原始图像’); x=1:225; ...
  • Python程序设计 简单的图像处理(1) 1.写个滤镜 照片照的好,不如滤镜用得好!一款好的滤镜软件可以让照片呈现不一样的风格乃至风情,修理照片需要扬长避短达到最佳效果。可是滤镜款式千百种,却没有一款专门为你...
  • 一,前言卷积神经网络(Constitutional Neural Networks, CNN)是在多层神经网络的基础上发展起来的针对图像分类和识别而特别设计的一种深度学习方法。先回顾一下多层神经网络: 多层神经网络包括一个输入层和一个...
  • 图像处理与识别

    2016-07-01 08:45:03
    图像处理与识别学习结   数字图像处理是对图像进行分析、加工、和处理,使其满足视觉、心理以及其他要求的技术。图像处理是信号处理在图像域上的一个应用。目前大多数的图像是以数字形式存储,因而图像处理很多...
  • 利用Qt和QPainter实现一个图像处理程序,有菜单栏、工具栏和状态栏  2.有图像选择对话框,以选择和读取图像  3.状态栏显示图像的像素,位深,导入图像的路径和鼠标所在点的像素点坐标  4.可以对图像缩放,旋转...
  • python 图像处理

    2018-06-19 14:51:01
    转自:点击打开链接第 1 章 基本的图像操作和处理本章讲解操作和处理图像的基础知识,将通过大量...1.1 PIL:Python图像处理类库PIL(Python Imaging Library Python,图像处理类库)提供了通用的图像处理功能,以...
  • 本人有过多年用FPGA做图像处理的...例如在一些分选设备中图像处理基本上用的都是FPGA,因为在其中相机从看到物料图像到给出执行指令之间的延时大概只有几毫秒,这就要求图像处理必须很快且延时固定,只有FPGA进行...
  • 实训要求用微信小程序实现对图像的智能识别,我选择的是用阿里云的身份证识别API对上传的身份证进行识别 参考了这个博客 微信小程序-OCR信息识别 并在这个博客基础上做了一些修改 身份证识别Api :文字识别 该...
1 2 3 4 5 ... 20
收藏数 214,905
精华内容 85,962