2018-04-17 09:15:49 HANNING563128766 阅读数 6947

最近在做毕业设计,涉及到了图像处理的知识,遇到觉得有用的就记录一下,原理性的东西可能不多,重要是用的啦~我用的是python3.6,废话不多说,先上效果图

可见,这里实现的是一个定点切割,怎么实现的呢?来看看代码:

from PIL import Image

im = Image.open('F:/test.jpg')
# 图片的宽度和高度
img_size = im.size
print("图片宽度和高度分别是{}".format(img_size))

left = 80
upper = 210
right = 505
lower = 640

region = im.crop((left,upper,right,lower))
region.save("F:/crop_test.jpg")

这段代码,实现的是从一张大图上切指定区域的某个部分,主要就是利用crop()函数,crop()的参数,而在看了下面这段定义之后,我们应该关注一下crop()函数的这个4-tuple参数了

def crop(self, box=None):
"""
Returns a rectangular region from this image. The box is a
4-tuple defining the left, upper, right, and lower pixel
coordinate.

Note: Prior to Pillow 3.4.0, this was a lazy operation.

:param box: The crop rectangle, as a (left, upper, right, lower)-tuple.
:rtype: :py:class:`~PIL.Image.Image`
:returns: An :py:class:`~PIL.Image.Image` object.
"""

现在具体讲怎么设置(left,upper,right,lower)这个参数,其实简单点来说就是“左上右下”的顺序,我之前那个是怎么实现切割的呢?我是怎么获取这些边界的呢,其实很笨的方法,我使用了ps的坐标,拖动的时候就可以看到对应像素,如下图:


好了,最简单的切割完成了,在这里在贴一个自动切割多块的代码,切割个数是yy * xx个,可自行修改,知道了原理大家也可以自由发挥哦~效果图和代码如下:


from PIL import Image

im = Image.open("F:/test.jpg")
# 图片的宽度和高度
img_size = im.size
print("图片宽度和高度分别是{}".format(img_size))

xx = 3
yy = 2
x = img_size[0] // xx
y = img_size[1] // yy
for j in range(yy):
for i in range(xx):
left = i*x
up = y*j
right = left + x
low = up + y
region = im.crop((left,up,right,low))
print((left,up,right,low))
temp = str(i)+str(j)
region.save("f:/test/"+temp+".png")

2018-08-20 20:55:49 dimei0938 阅读数 630

图像复原最基本的任务是去除图像中的噪声的同时,不丢失图像中的细节。然而抑制噪声(高频)与保留细节(高频)是一对矛盾的问题。
图像复原与图像增强都是为了改善图像的质量,但本质上有所区别。图像增强不考虑图像是如何退化的,而是试图用各种技术来增强图像的视觉效果;而图像复原需要知道图像退化的机制与过程,找到一种相应的逆处理方法,从而得到恢复后的图像。

1. 噪声

噪声可以分为加性噪声和乘性噪声两种。
细分,可以分为高斯噪声,椒盐噪声,均匀分布噪声,指数分布噪声,gamma分布噪声等。在matlab中,加入噪声只需要imnoise就可以实现。

2. 空域滤波

空域内的滤波复原方法,主要包括均值滤波复原、顺序统计滤波复原、和自适应滤波复原。

2.1 均值滤波复原

均值滤波复原就是用均值滤波算子作为卷积核计算。分为算术均值滤波和几何均值滤波。
在matlab中,算术均值滤波就是直接进行滤波:
A = imfilter(Img, psf);
而几何均值滤波则是对图像取对数,再进行滤波,然后取指数:A=exp(imfilter(log(Img),psf));
python中也可以用filter2d与numpy包来实现类似功能。
此外,还有一个逆谐波均值滤波器,有一个参数Q,用matlab实现的代码为(其实是写公式有些麻烦):

Q = 1.5;    A = imfilter(img.^(Q+1),psf)./imfilter(img.^Q,psf);

Q为正值时,可以去除椒噪声;Q为负值时,可以去除盐噪声。当Q = -1时,该滤波器为谐波均值滤波器。我也不知道opencv库中有没有这个功能(反正toturial里面没有),不过可以很简单的用numpy与filter2d来实现这个功能(照着公式填就完了)。

2.2 顺序统计滤波复原

顾名思义,顺序统计滤波就是把一个像素值周围的邻域所有元素排序,其最大值/最小值/中值就为该点复原后的值。这种方法可以用于去除椒盐噪声。在matlab中,用函数medfilt(中值滤波)与ordfilt(顺序滤波)来实现。在python中,我们还是用好用的numpy来实现。(着实很简单,如果需要我补上代码可以评论告诉我)

2.3 自适应滤波复原

自适应滤波也就是上一篇说过的维纳滤波。既然第二次提到了,那就给出一个示例代码(matlab不需要,有现成的wiener2):

def wiener(input,PSF,eps,K=0.01):        #维纳滤波,K=0.01
    input_fft=fft.fft2(input)
    PSF_fft=fft.fft2(PSF) +eps
    PSF_fft_1=np.conj(PSF_fft) /(np.abs(PSF_fft)**2 + K)
    result=fft.ifft2(input_fft * PSF_fft_1)
    result=np.abs(fft.fftshift(result))
    return result

虽然给了代码块,不过这里确实不是重点,维纳现在很少用了,自适应滤波器还是应用太少,就算用也用自适应LMS算法啥啥的。。

3. 图像复原方法

3.1 逆滤波复原

这是最简单的复原方法。其实就是傅里叶变换后,除以所用退化矩阵的傅里叶变换,再变回来,就是所谓逆滤波。这种方法其实不好用,对噪声及其敏感。除非我们知道噪声的分布(不太可能),不然会变得很乱。
不过还有一种改进,由于噪声是很高的频率部分,那可以傅里叶变换之后只在低频部分做逆滤波,不过这个范围很难确定,范围太小容易没有复原效果,范围太大又会增强噪声,还是不理想。
(不理想的东西就少说几句,反正用不到)

3.2 维纳滤波复原

维纳滤波复原对运动模糊复原效果较好。在matlab中用deconvwnr进行图像的维纳滤波复原。
维纳滤波引入了信噪比,当信噪比为0时其实就是逆滤波。用于逆滤波的算子可以写为:

%H为滤波用算子
G = 1./H.*(abs(H).^2./(abs(H).^2+NSR));

其实就是通过信噪比来自动选择上面所说的频率范围。。
(换汤不换药,实际上没好到哪去,不过复原原理本来就是这样)

3.3 约束最小二乘法复原

在matlab中,使用deconvreg来进行最小约束二乘法复原。这种方法需要知道噪声方差和均值的先验知识。
实际上,就是一个约束条件下,使得图像最平滑。用一个最小准则函数c,c 为图像的二阶导数在整个图像区域的积分。得到c的最小值的方法采用拉格朗日乘数法,所以这种方法叫约束最小二乘法复原。

close all;
clear all;
clc;
I = im2double(imread('img.jpg'));
[hei,wid,~] = size(I);
subplot(2,2,1),imshow(I);
title('原图像');
% 模拟运动模糊.
LEN = 21;
THETA = 11;
PSF = fspecial('motion', LEN, THETA);%产生运动模糊算子,即点扩展函数
blurred = imfilter(I, PSF, 'conv', 'circular');
subplot(2,2,2), imshow(blurred); title('模糊图像');
Pf = psf2otf(PSF,[hei,wid]);%退化函数的FFT
%% 添加加性噪声
noise_mean = 0;
noise_var = 0.00001;
blurred_noisy = imnoise(blurred, 'gaussian',noise_mean, noise_var);
subplot(2,2,3), imshow(blurred_noisy)
title('带运动模糊和噪声图像')

p = [0 -1 0;-1 4 -1;0 -1 0];%拉普拉斯模板,也就是二阶导
P = psf2otf(p,[hei,wid]);
gama = 0.001;
If = fft2(blurred_noisy);
numerator = conj(Pf);%conj函数,用于求一个复数的复共轭
denominator = Pf.^2 + gama*(P.^2);
deblurred2 = ifft2( numerator.*If./ denominator );%约束最小二乘方滤波在频率域中的表达式
subplot(2,2,4), imshow(deblurred2)
title('约束最小二乘方滤波后图像');

3.4 Lucy-Richardson复原

Lucy-Richardson法就是用迭代的方法实现一个加速收敛,迭代次数少了复原不够,迭代次数多了有振铃效应。至于原理,好像是包括了极大似然和EM算法,who cares 反正知道了迭代式就可以直接跨语言使用了,分析原理有时间再说啦。。
我们可以用画信噪比和峰值信噪比的曲线来确定最佳的迭代次数,直接代进去使用就可以了。顺便说一下,matlab中Lucy-Richardson复原的函数是deconvlucy

3.5 盲解卷积复原

前面这些复原方法,需要知道图像,退化时的psf。不过在实际应用中,psf一般不容易被知道,这种情况我们就可以用盲解卷积复原。不过我们还是需要输入一个psf的估计值,在matlab中我们用deconvblind来实现盲解卷积复原。
一般盲解卷积复原初步复原后会有很大的振铃效应,使用WEIGHT参数可以消除这些效应。首先调用edge查到图像中灰度变换较大的区域,然后膨胀图像以扩充处理区域;边界与灰度变化较大的地方会被设置为0。然后再对图像重建,搞来搞去就会消除大部分的振铃效应啦!(实际上我也没搞太懂,可以看看别人转的matlab程序,虽然他也是转载的,不过转到了原创里我也不知道能不能直接转,直接给出链接:https://blog.csdn.net/mingtian715/article/details/67637458

今天就这样。。这部分好难啊,我也没搞太清楚,希望有大牛可以在这方面,把我没说清楚的地方说清楚,可能日后仔细研究,看英文文献的时候会在番外部分给出详细的翻译和理论思路和推导吧。。

2016-09-09 00:53:31 lpsl1882 阅读数 2543

  图像处理分析过程中,检测特定的形状是重要的一步。霍夫变换(Hough)通过转换坐标系,将特定形状的检测映射到参数空间中,从而根据参数空间中的值来确定特定形状的相关信息。
  Hough变换的比较简单的应用例子有检测直线和检测圆。

检测直线

  设空间中有若干点,我们要判断这些点是否能构成一条直线,即为直线检测。平面中直线的通用公式为xcos(θ)+ysin(θ)=ρ。常用的y=wx+b公式,因为不能兼容y=b的情况,所以不能使用。对于某个点,其坐标是(xi,yi),过该点的直线有无数条,这些直线统一表示为xicos(θ)+yisin(θ)=ρ,其中xi,yi是常量。反过来看,代表这些直线的公式,可以看做θ为自变量,ρ为因变量,xi,yi为常量参数的直线公式。这样,在x-y空间过(xi,yi)的无数条直线,可以在θρ空间中用一条线代表。见下图:
  这里写图片描述
  这里写图片描述
  上图是x-y空间,下图是θρ空间。其中红、绿、蓝三条线可以汇聚成一个点,说明这三条线对应的点,其在θρ空间中的直线参数是一样的。反过来就是说,穿过这三个点的无数直线中,有“三”条直线,其θ,ρ值相同,这“三“条直线是一根直线,即这三个点可以共线。
  

检测圆

  设空间有若干点,我们要判断这些点是否能构成一个圆的轮廓,即为圆检测。圆的表达式为(xx)2+(yy)2=R,参数有x,y,R。这说明,圆对应的映射空间是三维的,即xyR空间。x,y都表示空间,因此我们可以暂时将R设为常量,构建xy空间,令x’为自变量,y’为因变量,作图如下:
  这里写图片描述
  这里写图片描述
  上图是x-y空间,下图是x’-y’空间。图中绘制了一个圆和一个矩形,其中圆的轮廓并不是完全规则的。经过Hough变换后,圆上的点的变换曲线基本汇聚在一起,而矩形上的点则不能汇聚,这样就检测到圆。由于我们获取的图像并不一定是规则图形,其在参数空间中不一定能汇聚到一个点,而是在一个区域中汇聚起来,为了容许这类误差,我们可以用窗来检测参数空间中的曲线汇聚区域,而不是找曲线汇聚点,以此来检测不完全规则的特定形状。
  如果我们不知道R的值,那么我们就需要给定R取值的离散区间[R1,R2...Rn],取该区间中的值,重复做n次Hough变换检测。这样的话工作量会非常大,为了提升效率,往往会借助图像中的其他特征。
  另外,我们可以看出,由于不知道圆的尺度,我们不得不重复做多次检测。在实际的形状检测工作中,我们并不知道需要检测的复杂形状,经过了何种平移、缩放、旋转甚至是扭曲,因此需要引入不变性特征,或者针对所有可能的平移、缩放、旋转变换情况,统统做一遍检测。物体检测跟踪需要相当多的计算量。据了解,人脑为了进行视觉模式识别,至少消耗了一半的神经资源,所以人可以闭目养神,却不能捂耳朵、捏住鼻子养神:)

2019-11-29 17:11:55 Stalla_s_bf 阅读数 24

数字图像处理作业四

观察图片傅里叶变换后的情况:

在这里插入图片描述
可以发现,图像在高频部分有较多的分布,且存在较多的横向的线条

思路一:运用简单的低通滤波器进行处理(高斯滤波器)

具体步骤如下

  1. 对图像进行填充的傅里叶变换
  2. 生成滤波函数,sigmoid = 20
  3. 将二者点乘
  4. 进行傅里叶逆变换输出函数

代码如下

f = imread('linelenna.jpg');
[m,n] = size(f);
figure, imshow(f)
Fp = fft2(f,2*m,2*n); % 得到使用填充的傅里叶变换
figure, imshow(log(1 + abs(Fp)), [])
sig = 20;
Hp = lpfilter('gaussian', 2*m,2*n, 2 * sig); % 生成一个大小为2*m,2*n的滤波函数Hp
Gp = Hp.*Fp; % 将变换乘以滤波函数,注意是点乘!!!
% imshow(Gp, [])
gp = real(ifft2(Gp)); % 获得G的傅里叶逆变换的实部
figure, imshow(gp, [])
gpc = gp(1:size(f,1), 1:size(f,2)); % 将左上部的矩形修剪为原始大小
figure, imshow(gpc, [])

结果如下:
在这里插入图片描述
发现图像处理的效果不是很理想,线条没有很好的处理,而且图片也变得模糊了

思路二:对傅里叶变换后的图片进行空间操作

具体步骤如下

  1. 对图像进行填充的傅里叶变换,得到Fp
  2. S = log(1 + abs(Fp));
  3. 对S中所有S(i,j)>=15的点进行操作,使S(i,j) = S(i+1,j)
  4. 加入高斯滤波
  5. 进行傅里叶逆变换输出函数

代码如下:

clear
close all
clc
f = imread('linelenna.jpg');
[m,n] = size(f);
figure, imshow(f)
Fp = fft2(f,2*m,2*n); % 得到使用填充的傅里叶变换
[x,y] = size(Fp);
S = log(1 + abs(Fp));
new_Fp = zeros(x,y);
for i = 2:x-1
    for j = 2:y-1
        if S(i,j)>= 15
            new_Fp(i,j) = Fp(i+1,j);
        else
            new_Fp(i,j) = Fp(i,j);
        end    
    end
end
figure, imshow(S, [])
sig = 20;
Hp = lpfilter('gaussian', 2*m,2*n, 2 * sig); % 生成一个大小为PQ(1)×PQ(2)的滤波函数Hp
Gp = Hp.*new_Fp; % 将变换乘以滤波函数,注意是点乘!!!
gp = real(ifft2(Gp)); % 获得G的傅里叶逆变换的实部
figure, imshow(gp, [])
gpc = gp(1:size(f,1), 1:size(f,2)); % 将左上部的矩形修剪为原始大小
figure, imshow(gpc, [])

得到的图片如下:
在这里插入图片描述
可见,脸部的处理效果较好,但是仍存在部分线条以及图片相对模糊

思路三:使用经过简单改变的理想滤波器

具体步骤如下

  1. 对图像进行填充的傅里叶变换,得到Fp
  2. S = log(1 + abs(Fp));
  3. 对S中所有S(i,j)>=9取出,二值化后放入新矩阵bw_new_Fp
  4. 生成一个矩形的滤波器bw
  5. new_Fp = Fp.*bw_new_Fp .*bw
  6. 对 new_Fp 进行傅里叶逆变换输出函数

bw_new_Fp 如下

在这里插入图片描述

bw如下

在这里插入图片描述

new_Fp如下

在这里插入图片描述
代码如下

clear
close all
clc
f = imread('linelenna.jpg');
[m,n] = size(f);
figure, imshow(f)
Fp = fft2(f,2*m,2*n); % 得到使用填充的傅里叶变换
[x,y] = size(Fp);
S = log(1 + abs(Fp));
new_Fp = zeros(x,y);
for i = 1:x
    for j = 1:y
        if S(i,j) >= 9
            new_Fp(i,j) = Fp(1,j);
        end    
    end
end
new_Fp2 = new_Fp;
bw_new_Fp = logical(abs(new_Fp));
bw = ones(2*m,2*n);
bw(round(2/6*m):round(10/6*m),:) = 0;
imshow(bw)
figure, imshow(bw_new_Fp, [])
new_Fp = Fp.*bw_new_Fp.*bw;
figure, imshow(log(1+abs(new_Fp)), [])
gp = real(ifft2(new_Fp)); % 获得G的傅里叶逆变换的实部
gpc = gp(1:size(f,1), 1:size(f,2)); % 将左上部的矩形修剪为原始大小
figure, imshow(gpc, [])

最终的结果如下

在这里插入图片描述
其结果有点之前的作业中,均值滤波器达到的效果。

遇到的问题与解决办法

问题一:傅里叶变换后直接输出全是黑色

代码如下:

i = imread('linelenna.jpg');
I = fft2(i);
figure;imshow(I, [])

解决办法:将图像经过Log(1+abs(I))变换即可

代码如下

i = imread('linelenna.jpg');
I = fft2(i);
S = log(1 + abs(I));
figure;imshow(S, [])
2019-08-09 16:18:44 qq_35166974 阅读数 30

最近整理笔记本,发现自己本科学习图像处理做的笔记,现在分享上来供大家学习,后面也会继续学习图像处理的相关知识,每天学习几个知识点,知识不怕多~

1.    图像掩膜:
图像掩膜就是用一张二值图与一张正常图片进行点乘,二值图黑色部分的值为0,白色部分值为1,点乘之后,黑色覆盖的部位的值变成0,白色部分的值保持不变,这就实现了掩膜,将图像没有用的部分去除,只留下感兴趣区域。
2.   图像锐化、滤波等实质
图像锐化和滤波等,其实就是将一张图像与一个矩阵模板进行卷积(函数为convn)。矩阵模板一般为奇数矩阵如3*3,5*5,7*7等,卷积的实质就是矩阵模板在图像矩阵上遍历一遍,矩阵模板和图像矩阵上对应的值相乘,最后相加得到一个值,将该值赋给输出图像上,如图所示,位置与矩阵模板的中心对应。注意矩阵模板所有值和一般为1,为1时图像明暗不变,小于1时图像变暗,大于1时图像变亮。


3.   图像的膨胀与腐蚀
MATLAB中图像膨胀的实现函数为imdilate(I,se),其中se为结构元素,一般用strel函数生成,如strel(‘disk’,5),生成一个半径为5的球形的结构元素。腐蚀函数为imerote(I,se)。膨胀和腐蚀都是针对图像中的较亮的色块,因此效果和我们理解的刚好相反,膨胀我们会看到黑色部分变小,腐蚀我们会看到黑色部分变大。
开运算:先腐蚀后膨胀imopen函数
作用:消除细小孔洞
闭运算:先膨胀后腐蚀imclose函数
作用:消除黑色细小物体

4.   图像二值化
MATLAB中的函数im2bw函数可以是实现图像的二值化处理,但是阈值的选取比较困难。有两种方法选取阈值:
迭代法:将图像分为前景和目标,迭代求出前景和目标平均灰度值最为二值化的阈值。
大津阈值(也叫最大类间方差法):通过函数graythresh(I)可以求出大津阈值。
5.   边缘检测(明日学习重点)
常用的边缘检测算法有soble算法和Laplacian算法。Soble算法有垂直方向和水平方向导数的问题,而Laplacian算法既可以做边缘检测,也可以做图像锐化,同时也不局限于水平方向或垂直方向。
边缘检测的实质是:图像的边缘一般是图像中像素变化最剧烈的位置,因此边缘处的梯度最大,因此寻找边界的原理是找到图像中局部梯度最大的位置,此处即为图像的边缘。

BMP文件数据解析

阅读数 899

没有更多推荐了,返回首页