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

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

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

在后半部分的图像处理算法介绍部分,偶尔为了便于理解,本书配备了必要的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;
endmountains(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);
endif (frame_size(2) + position_in_target(2) > TargetRows)position_in_target(2) = TargetRows - frame_size(2);
endMaskTarget = 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
endimshow(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:heightfor j = 1: widthNumPixel(V(i,j) + 1) = NumPixel(V(i,j) + 1) + 1;end
endProbPixel = zeros(1,256);
for i = 1:256ProbPixel(i) = NumPixel(i) / (height * width * 1.0);
endCumuPixel = cumsum(ProbPixel);
CumuPixel = uint8(255 .* CumuPixel + 0.5);for i = 1:height  for j = 1: width  if V(i,j)==0V(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
endHist = 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;elsesubY = HSize;yU = i - 1;yB = i;endxI = 1;for j = 1:NrX+1if j == 1  subX = floor(WSize/2);xL = 1;xR = 1;elseif j == NrX+1subX = floor(WSize/2);xL = NrX;xR = NrX;elsesubX = WSize;xL = j - 1;xR = j;endUL = 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 - 1inverseI = subY - i;for j = 0:subX - 1inverseJ = 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;endend%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%output(yI:yI+subY-1, xI:xI+subX-1) = sImage;xI = xI + subX;endyI = 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:numpxatmSum = atmSum + ImVec(indices(ind),:);
endatmospheric = atmSum / numpx;%求解透射率,并通过omega参数来选择保留一定程度的雾霾,以免损坏真实感
omega = 0.95;
im = zeros(size(imageRGB));for ind = 1:3 im(:,:,ind) = imageRGB(:,:,ind)./atmospheric(ind);
enddark_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: na(i,j) = min(r(i,j), g(i,j));a(i,j)= min(a(i,j), b(i,j));end
endd = ones(15,15);
fun = @(block_struct)min(min(block_struct.data))*d;
dark = blockproc(a, [15 15], fun); dark = dark(1:m, 1:n);

本书源起

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

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

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


关于其他补充代码

如果上述代码发布有缺漏,或者需要其他补充代码,请到QQ群 (155911675)联系店小二获取,注意:

  1. 请看清楚入群问题,并据实作答(否则将无法入群);——诚实守信非常重要,无论何时,都不要出卖自己的诚信!

  2. 入群后请主动联系店小二,说明来意(否则就会被删除),本群仅做购书或补充代码获取之临时使用,完成操作后请主动退群。

  3. 店小二是临时工,不会24小时在线。请尽量在工作日工作时间联系,否则入群请求可能不会被应答。

【图像处理中的数学修炼(第1版)】一书之代码相关推荐

  1. 【图像处理中的数学修炼(第1版)】总纲:详解图像背后的数学原理

    数字图像处理技术的研究与开发对数学基础的要求很高,一些不断涌现的新方法中,眼花缭乱的数学推导令很多期待深入研究的人望而却步.一个正规理工科学生大致已经具备了包括微积分.线性代数.概率论在内的数学基础. ...

  2. 【图像处理中的数学修炼(第1版)】的特别说明及其勘误表

    由清华大学出版社出版的<图像处理中的数学修炼>这本书是今年3月左右正式上市销售的.现在三个多月过去了,已经积累了大量的读者.但是,随着读者数量的增加,近来有部分读者在跟我交流和咨询的时候表 ...

  3. 图像处理中常用数学知识

    2.3.3 赋范空间 每个实数或复数,都有相对应的绝对值或者模,每一个n维矢量,也都可以定义其长度.如果把"长度"的概念推广到一般抽象空间中的元素上,就可以得到范数这个概念. 本节 ...

  4. 机器学习中的数学修炼(含勘误表!)

    机器学习中的数学修炼--为你打开一道通往机器学习世界的数学之门 数学是机器学习和数据科学的基础,任何期望涉足相关领域并切实领悟具体技术与方法的人都无法绕过数学这一关.本书系统地整理并介绍了机器学习中所 ...

  5. 游戏中的数学与物理学 第二版_在游戏中启蒙幼儿的数学能力和逻辑思维能力...

    同事奥北是个很有教育想法的妈妈,怀孕的时候就学习很多育儿知识,孩子出生后,她就在生活中,有意识的去培养孩子的各种能力.最近,孩子到了3岁后,她想要开始逐步培养孩子良好的逻辑思维能力.她本想着送孩子到早 ...

  6. 游戏中的数学与物理学 第二版_在数学课堂中适度开展游戏活动,可以提高课堂教学效率...

    [摘要]小学生是以无意注意为主的,而无意注意又受兴趣的影响,更何况数学是一门比较抽象的学科.因此,在数学课中适度引入游戏是很有必要的.基于学生的心理特征,学生需要游戏,恰当的游戏不仅能够调节课堂气氛, ...

  7. Python机器学习中的数学原理详解(补充勘误表)

    数学是机器学习和数据科学的基础,任何期望涉足相关领域并切实领悟具体技术与方法的人都无法绕过数学这一关.在一篇题为<放弃幻想,搞AI必须过数学关>的网文中,作者一针见血地指出想从事AI相关工 ...

  8. 2019中科大数学考研复试题(回忆版)

    **2019中科大数学考研复试题(回忆版)** 实变函数 1.平面上横坐标或纵坐标为有理数的点集测度为零. 2.{fn}\{f_{n}\}{fn​}是一列可测函数,则 (a)若∫A∣fn−fn−1∣d ...

  9. 图像处理基础中的数学知识及其物理意义

    本文主要参考内容:1.https://www.cnblogs.com/dengdan890730/p/6145585.html 2.https://blog.csdn.net/qq_40238526/ ...

最新文章

  1. 【MySQL经典案例分析】 Waiting for table metadata lock
  2. 2016重庆计算机一级考试题型,重庆计算机一级考试真题2016年最新(笔试+上机).doc...
  3. SQL Transcation的一些总结
  4. LINQ to XML 编程基础
  5. Java学习笔记2.3.3 运算符与表达式 - 关系运算符
  6. Android图片缩放方法
  7. 用VB使用花式画笔实现流动的选取框
  8. bzoj 1414 bzoj 3705: [ZJOI2009]对称的正方形(二维Hash)
  9. 短视频APP测试要点
  10. python 读取并裁剪nc文件
  11. Android水平仪实训报告,测量实训报告【三篇】
  12. php houdini,houdini中文翻译.pdf
  13. 【经典策略系列】之 Dual Thrust 交易策略
  14. 绿色到黄色到红色的颜色渐变
  15. 朋友python多个逻辑条件判断_Python小课笔记--Python控制流:if逻辑判断
  16. 【CF802O】April Fools‘ Problem (hard)(wqs二分,模拟费用流,老鼠进洞)
  17. kprobe 的 3 种使用
  18. tplink控制上网设备_tplink路由器如何控制小孩的使用上网时间
  19. 百万级别中文文本分类
  20. word2019设置背景色为护眼的绿色

热门文章

  1. ailx10的hacknet攻略007
  2. 大数运算之100的阶乘(C语言实现)
  3. 如何正确测试电源的纹波?
  4. 什么东西可以替代触屏笔?四款值得推荐的电容笔分享
  5. 【字节2019春招】万万没有想到之聪明的编辑
  6. html hdr文件,hdr文件是什么?hdr和蓝光哪个清晰?
  7. 欧姆龙e5dc温控器_欧姆龙E5DC-RX2DSM-802用户手册 数字温度控制器手册 - 广州凌控...
  8. 张宇基础30讲 第6讲 中值定理
  9. 又好又快,免费学习编程的9个地方
  10. 易基因 | 微量样本DNA甲基化测序分析怎么做?25.617分文章告诉你