【图像处理中的数学修炼(第2版)】代码

自《图像处理中的数学修炼》原书第一版于2017年2月上市以来,加印重印多次,在京东和当当等主流在线购书网站上已经累计有超过3200个购买评论,并且在这两个网站上的好评度都超过99%。结合第一版书籍读者给出的反馈,同时为了适应相关技术的快速发展,在首版发行三年之后的2020年,笔者再度与清华大学出版社合作,乘势推出全新的《图像处理中的数学修炼》(第2版)。

新版的《图像处理中的数学修炼》全书共分十二章(*第一版书一共是八章):其中前五章主要是图像处理中最重要、最常用的数学基础,这也是每个期望进行图像处理研究和学习的人必须要掌握的基础,这部分内容包括:

  • 第1章 必不可少的数学基础(主要是微积分和场论)
  • 第2章 更进一步的数学内容(包括傅立叶变换、凸优化、数值计算、偏微分方程等)
  • 第3章 泛函分析及变分法
  • 第4章 概率论基础
  • 第5章 统计推断

第六至第十二章(共7章)则结合图像处理领域比较流行的研究话题,举例说明前五章中数学基础在图像处理中的具体应用。这部分内容包括:

  • 第6章 子带编码与小波变换
  • 第7章 正交变换与图像压缩
  • 第8章 无所不在的高斯分布(主要是各种微分算子及边缘保持的图像去噪平滑技术)
  • 第9章 空间域图像平滑与降噪(维纳滤波、双边滤波、导引滤波、字典学习等)
  • 第10章 图像融合与抠图技术(例如贝叶斯抠图技术、泊松方程应用等)
  • 第11章 处理彩色图像(色彩空间理论与彩色图像增强,例如CLAHE等)
  • 第12章 图像去雾

对于阅读本书时的困惑和问题,以及发现的书中的纰漏、错误等,欢迎在博文下方留言,或者直接发邮件给作者(邮件地址见博客网页版左侧栏目)。本文后面给出了本书中配套的相应代码。但是,需要特别提醒广大读者注意:

代码或者编程不是这本书的重点!
代码或者编程不是这本书的重点!
代码或者编程不是这本书的重点!

所以,请千万不要把这本书用来作为你入门图像处理编程的扫盲书!!!如果你更想学习如何用MATLAB进行图像处理应用方面的编程开发,可以参考我的另外一本书《数字图像处理:原理与实践(MATLAB版)》


P255

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,[]);

P257

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

P258

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,[]);

P259

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');

P283

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'); 

P284

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'); 

P292

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  

P343

function [f,noise] = mywiener2(g, nhood, noise)

if (nargin<3)
    noise = [];
end

% Estimate the local mean of f.
localMean = filter2(ones(nhood), g) / prod(nhood);

% Estimate of the local variance of f.
localVar = filter2(ones(nhood), g.^2) / prod(nhood) - localMean.^2;

% Estimate the noise power if necessary.
if (isempty(noise))
  noise = mean2(localVar);
end

% Compute result
% f = localMean + (max(0, localVar - noise) ./ ...
%           max(localVar, noise)) .* (g - localMean);
%
% Computation is split up to minimize use of memory for temp arrays.
f = g - localMean;
g = localVar - noise; 
g = max(g, 0);

f = localMean + ((f ./ max(localVar, noise)) .* g);

P344

RGB = imread('saturn.png');
I = rgb2gray(RGB);
I = I(601:1000,1:600);

J = imnoise(I,'gaussian',0,0.005);
J = im2double(J);

K = mywiener2(J,[5 5]);

figure;
imshow(I), title('original image');

figure;
subplot(1,2,1), subimage(J), title('noised image');
subplot(1,2,2), subimage(K), title('denoised image');

P345-P348

【代码链接】

P355

function q = guidedfilter(I, p, r, eps)

%   - guidance image: I (should be a gray-scale/single channel image)
%   - filtering input image: p (should be a gray-scale/single channel image)
%   - local window radius: r
%   - regularization parameter: eps

[hei, wid] = size(I);
N = boxfilter(ones(hei, wid), r); 

mean_I = boxfilter(I, r) ./ N;
mean_p = boxfilter(p, r) ./ N;
mean_Ip = boxfilter(I.*p, r) ./ N;
% this is the covariance of (I, p) in each local patch.
cov_Ip = mean_Ip - mean_I .* mean_p; 

mean_II = boxfilter(I.*I, r) ./ N;
var_I = mean_II - mean_I .* mean_I;

a = cov_Ip ./ (var_I + eps); 
b = mean_p - a .* mean_I; 

mean_a = boxfilter(a, r) ./ N;
mean_b = boxfilter(b, r) ./ N;

q = mean_a .* I + mean_b; 
end

P356

function imDst = boxfilter(imSrc, r)

%   BOXFILTER   O(1) time box filtering using cumulative sum
%
%   - Definition imDst(x, y)=sum(sum(imSrc(x-r:x+r,y-r:y+r)));
%   - Running time independent of r; 
%   - Equivalent to the function: colfilt(imSrc, [2*r+1, 2*r+1], 'sliding', @sum);
%   - But much faster.

[hei, wid] = size(imSrc);
imDst = zeros(size(imSrc));

%cumulative sum over Y axis
imCum = cumsum(imSrc, 1);
%difference over Y axis
imDst(1:r+1, :) = imCum(1+r:2*r+1, :);
imDst(r+2:hei-r, :) = imCum(2*r+2:hei, :) - imCum(1:hei-2*r-1, :);
imDst(hei-r+1:hei, :) = repmat(imCum(hei, :), [r, 1]) - imCum(hei-2*r:hei-r-1, :);

%cumulative sum over X axis
imCum = cumsum(imDst, 2);
%difference over Y axis
imDst(:, 1:r+1) = imCum(:, 1+r:2*r+1);
imDst(:, r+2:wid-r) = imCum(:, 2*r+2:wid) - imCum(:, 1:wid-2*r-1);
imDst(:, wid-r+1:wid) = repmat(imCum(:, wid), [1, r]) - imCum(:, wid-2*r:wid-r-1);
end

P357

I = double(imread('cat.bmp')) / 255;
p = I;
r = 4; % try r=2, 4, or 8
eps = 0.2^2; % try eps=0.1^2, 0.2^2, 0.4^2

O = guidedfilter(I, p, r, eps);

subplot(121), imshow(I);
subplot(122), imshow(O);

P368-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,:);

P368-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));

P369

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));

P371-P374(泊松融合、泊松编辑)

【代码下载链接】

【补充代码链接】

P376-P381(贝叶斯融合)

【代码下载链接】

P404-P406(直方图均衡)

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

 

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)

 

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
		V(i,j) = CumuPixel(V(i,j));
	end
end
 
V = im2double(V);
hsvImg(:,:,3) = V;
outputImg = hsv2rgb(hsvImg);
imshow(outputImg);

P408-P413(CLAHE)

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);

 

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);  

 

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

 

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, []);

【补充代码链接】

P415

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('originalimage');
subplot(2,3,4),imhist(img),title('originalimage');
subplot(2,3,2),imshow(img_ref),title('referenceimage');
subplot(2,3,5),imhist(img_ref),title('referenceimage');
subplot(2,3,3),imshow(J),title('outputimage');
subplot(2,3,6),imhist(J),title('outputimage');

P421-P422(暗通道先验的图像去雾)

%求一幅图像的暗通道图,窗口大小为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);

 

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);

【补充代码链接】

 

P424-P425(优化对比度图像去雾)

【代码下载链接】


Reminder

  • 代码整理仓促,可能有错误或者纰漏,如果你发现哪里有问题(包括页码标识有误),请在博文下方留言或直接发邮件给作者(邮件地址可参见网页版博客左侧【图像处理】栏目);
  • 部分网盘链接需要访问码,你可以到QQ群(155911675)中找店小二获取。本书代码仅供已经购书之读者参考学习,未购书者(包括借阅者)、购买盗版书、电子书或二手书者勿扰。
  • 请看清楚入群问题,并据实作答(否则将无法入群);
  • 入群后请主动联系店小二,说明来意(否则就会被删除),本群仅做购书或补充代码获取之临时使用,完成操作后请主动退群。
  • 店小二是临时工,不会24小时在线。请尽量在工作日工作时间联系,否则入群请求可能不会被应答。

 

 

  • 6
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

白马负金羁

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值