第一章 基本的图像操作和处理

  • 1.1 PIL:Python图像处理类库
    • 1.1.1转换图像格式
    • 1.1.2创建缩略图
    • 1.1.3复制和粘贴图像区域
    • 1.1.4调整尺寸和旋转
  • 1.2Matplotlib
    • 1.2.1绘制图像、点和线
    • 1.2.2图像轮廓和直方图
    • 1.2.3交互式标注
  • 1.3NumPy
    • 1.3.1图像数组表示
    • 1.3.2灰度变换
    • 1.3.3直方图均衡化
    • 1.3.4图像平均
    • 1.3.5使用pickle模块
  • 1.4SciPy
    • 1.4.1图像模糊
    • 1.4.2图像导数
    • 1.4.3形态学:对象计数
  • 1.5总结

1.1 PIL:Python图像处理类库

    PIL(Python Imaging Library Python,图像处理类库)提供了通用的图像处理功能,以及大量有用的基本图像操作,比如图像缩放、裁剪、旋转、颜色转换等。

1.1.1转换图像格式

    通过 save() 方法,PIL 可以将图像保存成多种格式的文件。

save(filename,format)

代码:

from PIL import Imageim = Image.open('JMU1.jpg', "r")
im1 = im.save('JMU1.png', 'png')

结果:

分析:
    通过 save() 方法成功将jpg图像重新保存成png格式。

1.1.2创建缩略图

    thumbnail()方法接受一个元组参数(该参数指定生成缩略图的大小),然后将图像转换成符合元组参数指定大小的缩率图。
    例如,创建最长边为128像素的缩略图,可以使用下列命令:

pil_im.thumbnail((128,128))

代码1:

from PIL import Image
from pylab import *
im = Image.open('JMU1.jpg', "r")
subplot(121)
title('(a)')
axis('off')
imshow(im)im.save('JMU1.png', 'png')
im.thumbnail((128, 128), resample=Image.BICUBIC)
subplot(122)
title('(b)')
axis('off')
imshow(im)
show()

结果1:

代码2:

from PIL import Imageim = Image.open('JMU1.jpg', "r")
im.save('JMU1.png', 'png')
im.show()
im.thumbnail((128, 128), resample=Image.BICUBIC)
im.show()

结果2:

分析:
    从结果1中可以看出,图像在同样大小的情况下展示,会变得模糊;从结果2中可以看出,正常情况下展示指定像素的缩略图,图像会变小。

1.1.3复制和粘贴图像区域

    使用crop()方法可以从一幅图像中裁剪指定区域:

box=(100,100,400,400)
region=pil_im.crop(box)

    该区域使用四元组来指定。四元组的坐标依次是(左,上,右,下)。PIL中指定坐标系的左上角坐标为(0,0)。我们可以旋转上面代码中获取的区域,然后使用paste()方法将该区域放回去,具体实现如下:

region=region.transpose(Image.ROTATE_180)
pil_im.paste(region,box)

代码:

from PIL import Image
from pylab import *
im = Image.open('JMU1.jpg', "r")
subplot(131)
title('(a)')
axis('off')
imshow(im)box = (200,350,400,450)
subplot(132)
title('(b)')
axis('off')
imshow(im.crop(box))region = im.crop(box)
im.paste(region,(400,200),None)
subplot(133)
title('(c)')
axis('off')
imshow(im)
show()

结果:

分析:
    从图像中裁剪的区域box = (200,350,400,450)表示裁剪区域左上角的x坐标为200,左上角y坐标为350,右下角x坐标为400,右下角y坐标为450,如结果中的(b)所示。使用paste()方法将裁剪的区域粘贴在左上角位置为(400,200)的区域。

1.1.4调整尺寸和旋转

    调用resize()方法调整一幅图像的尺寸。

out=pil_im.resize((128,128))

    调用rotate()方法旋转一幅图像,使用逆时针方式表示旋转角度。

out=pil_im.rotate(45)

代码:

from PIL import Image
from pylab import *
im = Image.open('boy.jpg', "r")
subplot(331)
title('(a)')
axis('off')
imshow(im)Image.FLIP_LEFT_RIGHT = im.transpose(Image.FLIP_LEFT_RIGHT)
subplot(332)
title('(b)')
axis('off')
imshow(Image.FLIP_LEFT_RIGHT)Image.FLIP_TOP_BOTTOM = im.transpose(Image.FLIP_TOP_BOTTOM)
subplot(333)
title('(c)')
axis('off')
imshow(Image.FLIP_TOP_BOTTOM)Image.ROTATE_45 = im.rotate(45)
subplot(334)
title('(d)')
axis('off')
imshow(Image.ROTATE_45)Image.ROTATE_90 = im.transpose(Image.ROTATE_90)
subplot(335)
title('(e)')
axis('off')
imshow(Image.ROTATE_90)Image.ROTATE_180 = im.transpose(Image.ROTATE_180)
subplot(336)
title('(f)')
axis('off')
imshow(Image.ROTATE_180)Image.ROTATE_270 = im.transpose( Image.ROTATE_270)
subplot(337)
title('(g)')
axis('off')
imshow( Image.ROTATE_270)Image.TRANSPOSE = im.transpose(Image.TRANSPOSE)
subplot(338)
title('(h)')
axis('off')
imshow(Image.TRANSPOSE)Image.TRANSVERSE = im.transpose(Image.TRANSVERSE)
subplot(339)
title('(i)')
axis('off')
imshow(Image.TRANSVERSE)show()

结果:

分析:
    (b)将图像左右翻转,(c)将图像上下翻转,(d)将图像逆时针旋转45°,(e)将图像逆时针旋转90°,(f)将图像逆时针旋转180°,(g)将图像逆时针旋转270°,(h)将图像进行转置(相当于顺时针旋转90°),(i)将图像进行转置,再水平翻转。

1.2Matplotlib

    处理数学运算、绘制图表,或者在图像上绘制点、直线和曲线时,Matplotlib是个很好的类库,具有比PIL更强大的绘图功能。

1.2.1绘制图像、点和线

代码:

from PIL import Image
from pylab import *# 添加中文字体支持
from matplotlib.font_manager import FontPropertiesfont = FontProperties(fname=r"c:\windows\fonts\SimSun.ttc", size=14)# 读取图像到数组中
im = array(Image.open('JMU3.jpg'))
figure()# 绘制有坐标轴的
subplot(121)
imshow(im)
x = [100, 100, 400, 400]
y = [200, 500, 200, 500]# 使用红色星状标记绘制点
plot(x, y, 'r*')# 绘制连接两个点的线(默认为蓝色)
plot(x[:2], y[:2])
title(u'带坐标轴', fontproperties=font)# 不显示坐标轴的
subplot(122)
imshow(im)
x = [100, 100, 400, 400]
y = [200, 500, 200, 500]plot(x, y, 'r*')
plot(x[:2], y[:2])
axis('off')
title(u'不带坐标轴', fontproperties=font)show()
# show()命令首先打开图形用户界面(GUI),然后新建一个窗口,该图形用户界面会循环阻断脚本,然后暂停,
# 直到最后一个图像窗口关闭。每个脚本里,只能调用一次show()命令,通常相似脚本的结尾调用。

结果:

    axis(‘off’) 命令可以使坐标轴不显示。
    在绘图时,有很多选项可以控制图像的颜色和样式。最有用的一些短命令如表1-1、表1-2和表1-3所示。使用方法见下面的例子:

1.2.2图像轮廓和直方图

    用PIL的convert()方法将图像转化为灰度图像。用hist()函数绘制(灰度)图像的直方图。
代码:

from PIL import Image
from pylab import *# 添加中文字体支持
from matplotlib.font_manager import FontProperties
font = FontProperties(fname=r"c:\windows\fonts\SimSun.ttc", size=14)
im = array(Image.open("JMU2.jpg").convert('L'))  # 打开图像,并转成灰度图像figure()subplot(131)
axis('off')
imshow(im)
axis('equal')
axis('off')
title(u'(a)原图像', fontproperties=font)# 使用颜色信息
subplot(132)
gray()
# 在原点的左上角显示轮廓图像
contour(im, origin='image')
axis('equal')
axis('off')
title(u'(b)图像轮廓', fontproperties=font)subplot(133)
hist(im.flatten(), 128)
title(u'(c)图像直方图', fontproperties=font)
plt.xlim([0,260])
plt.ylim([0,11000])show()

结果:

1.2.3交互式标注

    有时用户需要和某些应用交互,例如在一幅图像中标记一些点,或者标注一些训练数据。PyLab库中的ginput()函数就可以实现交互式标注。
代码:

from PIL import Image
from pylab import *im = array(Image.open('JMU2.jpg'))
imshow(im)
print('Please click 3 points')
x = ginput(3)
print('you clicked:', x)
show()

结果:

分析:
    用ginput()交互注释,代码中设置的交互注释数据点设置为3个,显示读取的图像后,然后注释,会将注释点的坐标打印出来。

1.3NumPy

    NumPy是非常有名的 Python 科学计算工具包,其中包含了大量有用的思想,比如数组对象(用来表示向量、矩阵、图像等)以及线性代数函数。NumPy中的数组对象可以帮助实现数组中重要的操作,比如矩阵乘积、转置、解方程系统、向量乘积和归一化, 这为图像变形、对变化进行建模、图像分类、图像聚类等提供了基础。

1.3.1图像数组表示

    NumPy中的数组对象是多维的,可以用来表示向量、矩阵和图像。一个数组对象很像一个列表(或者是列表的列表),但是数组中所有的元素必须具有相同的数据类型。除非创建数组对象时指定数据类型,否则数据类型会按照数据的类型自动确定。
代码:

from PIL import Image
from pylab import *im = array(Image.open('JMU2.jpg'))
print(im.shape, im.dtype)
im = array(Image.open('JMU2.jpg').convert('L'),'f')
print(im.shape, im.dtype)

结果:

分析:
    每行的第一个元组表示图像数组的大小(行、列、颜色通道),紧接着的字符串表 示数组元素的数据类型。因为图像通常被编码成无符号八位整数(uint8),所以在第一种情况下,载入图像并将其转换到数组中,数组的数据类型为“uint8”。在第二种情况下,对图像进行灰度化处理,并且在创建数组时使用额外的参数“f”;该参数将数据类型转换为浮点型。

1.3.2灰度变换

    将图像读入 NumPy 数组对象后,我们可以对它们执行任意数学操作。一个简单的例子就是图像的灰度变换。
代码:

from PIL import Image
from numpy import *
from pylab import *im = array(Image.open("JMU3.jpg").convert('L'))
print(int(im.min()), int(im.max()))im2 = 255 - im  # 对图像进行反相处理
print(int(im2.min()), int(im2.max()))im3 = (100.0/255) * im + 100   # 将图像像素值变换到 100...200 区间
print(int(im3.min()), int(im3.max()))im4 = 255.0 * (im/255.0)**2   # 对图像像素值求平方后得到的图像
print(int(im4.min()), int(im4.max()))figure()
gray()
subplot(1, 3, 1)
imshow(im2)
axis('off')
title(r'(a) $f(x)=255-x$')subplot(1, 3, 2)
imshow(im3)
axis('off')
title(r'(b) $f(x)=\frac{100}{255}x+100$')subplot(1, 3, 3)
imshow(im4)
axis('off')
title(r'(c) $f(x)=255(\frac{x}{255})^2$')
show()

结果:


分析:
    (a)对图像进行反相处理,(b)将图像的像素值变换到100…200区间,(c)对图像像素值求平方后得到的图像。

1.3.3直方图均衡化

    直方图均衡化是指将一幅图像的灰度直方图变平,使变换后的图像中每个灰度值的分布概率都相同。
代码:

import cv2
import matplotlib.pyplot as plt
import numpy as npgray_level = 256  # 灰度级def pixel_probability(img):assert isinstance(img, np.ndarray)prob = np.zeros(shape=(256))for rv in img:for cv in rv:prob[cv] += 1r, c = img.shapeprob = prob / (r * c)return probdef probability_to_histogram(img, prob):prob = np.cumsum(prob)  # 累计概率img_map = [int(i * prob[i]) for i in range(256)]  # 像素值映射# 像素值替换assert isinstance(img, np.ndarray)r, c = img.shapefor ri in range(r):for ci in range(c):img[ri, ci] = img_map[img[ri, ci]]return imgdef plot(y, name):plt.figure(num=name)plt.bar([i for i in range(gray_level)], y, width=1)if __name__ == '__main__':img = cv2.imread("cat.jpg", 0)  # 读取灰度图prob = pixel_probability(img)plot(prob, "原图直方图")# 直方图均衡化img = probability_to_histogram(img, prob)cv2.imwrite("source_hist.jpg", img)  # 保存图像prob = pixel_probability(img)plot(prob, "直方图均衡化结果")plt.show()

结果:

分析:
    均衡化之后,图像的亮度变得比较均衡,图像一些细节也得以观察到。

1.3.4图像平均

    图像平均操作是减少图像噪声的一种简单方式,通常用于艺术特效。可以简单地从图像列表中计算出一幅平均图像。假设所有的图像具有相同的大小,我们可以将这些图像简单地相加,然后除以图像的数目,来计算平均图像。

1.3.5使用pickle模块

    如果想要保存一些结果或者数据以方便后续使用,Python中的pickle模块非常有用。pickle模块可以接受几乎所有的Python对象,并且将其转换成字符串表示,该过程叫做封装。从字符串表示中重构该对象,称为拆封。 这些字符串表示可以方便地存储和传输。

1.4SciPy

    SciPy是建立在NumPy基础上,用于数值运算的开源工具包。SciPy提供很多高效的操作,可以实现数值积分、优化、统计、信号处理,以及对我们来说最重要的图像处理功能。

1.4.1图像模糊

    图像的高斯模糊是非常经典的图像卷积例子。本质上,图像模糊就是将(灰度)图像III和一个高斯核进行卷积操作:
Iσ=I∗GσI_{\sigma }=I*G_{\sigma} Iσ​=I∗Gσ​
其中∗*∗表示卷积操作:GσG_{\sigma}Gσ​是标准差为σ\sigmaσ的二维高斯核,定义为:
Gσ=12πσe−(x2+y2)/2σ2G_{\sigma} =\frac{1}{2\pi \sigma }e^{-(x^{2}+y^{2})/2\sigma ^{2}}Gσ​=2πσ1​e−(x2+y2)/2σ2
代码:

from PIL import Image
from pylab import *
from scipy.ndimage import filters# 添加中文字体支持
from matplotlib.font_manager import FontProperties
font = FontProperties(fname=r"c:\\windows\\fonts\\SimSun.ttc", size=14)im = array(Image.open('JMU2.jpg').convert('L'))figure()
gray()
axis('off')
subplot(1, 4, 1)
axis('off')
title(u'原图', fontproperties=font)
imshow(im)for bi, blur in enumerate([2, 5, 10]):im2 = zeros(im.shape)im2 = filters.gaussian_filter(im, blur)im2 = np.uint8(im2)imNum=str(blur)subplot(1, 4, 2 + bi)axis('off')title(u'标准差为'+imNum, fontproperties=font)imshow(im2)show()

结果:

分析:
    随着标准差σ\sigmaσ的增大,图像的模糊程度也增大,图像丢失的细节也越多。

1.4.2图像导数

    强度的变化可以用灰度图像III的x和yx和yx和y方向导数Ix和IyI_{x}和I_{y}Ix​和Iy​进行描述。
    图像的梯度向量为▽I=[Ix,Iy]T\triangledown I=[I_{x},I_{y}]^{T}▽I=[Ix​,Iy​]T。梯度有两个重要的属性,一是梯度的大小:
∣▽I∣=Ix2+Iy2\left | \triangledown I \right |=\sqrt{I_{x}^{2}+I_{y}^{2}}∣▽I∣=Ix2​+Iy2​​
它描述了图像强度变化的强弱,一是梯度的角度:
α=arctan2(Iy,Ix)\alpha =arctan2(I_{y},I_{x})α=arctan2(Iy​,Ix​)
描述了图像中在每个点(像素)上强度变化最大的方向。
    我们可以用离散近视的方式来计算图像的导数。图像导数大多数可以通过卷积简单地实现:
Ix=I∗Dx和Iy=I∗DyI_{x}=I*D_{x}和I_{y}=I*D_{y}Ix​=I∗Dx​和Iy​=I∗Dy​
对于Dx和DyD_{x}和D_{y}Dx​和Dy​,通常选择Prewitt滤波器或者Sobel滤波器。这些导数滤波器可以使用scipy.ndimage.filters模块的标准卷积操作来简单地实现。
代码:

from PIL import Image
from pylab import *
from scipy.ndimage import filters
import numpy# 添加中文字体支持
from matplotlib.font_manager import FontProperties
font = FontProperties(fname=r"c:\windows\fonts\SimSun.ttc", size=14)im = array(Image.open('JMU3.jpg').convert('L'))
gray()subplot(1, 4, 1)
axis('off')
title(u'(a)原始灰度图像', fontproperties=font)
imshow(im)# Sobel derivative filters
imx = zeros(im.shape)
filters.sobel(im, 1, imx)
subplot(1, 4, 2)
axis('off')
title(u'(b)x导数图像', fontproperties=font)
imshow(imx)imy = zeros(im.shape)
filters.sobel(im, 0, imy)
subplot(1, 4, 3)
axis('off')
title(u'(c)y导数图像', fontproperties=font)
imshow(imy)mag = 255-numpy.sqrt(imx**2 + imy**2)
subplot(1, 4, 4)
title(u'(d)梯度大小图像', fontproperties=font)
axis('off')
imshow(mag)show()

结果:

分析:
    在这个方法中,滤波器的尺度需要随着图像分辨率的变化而变化。为了在图像噪声方面更稳健,以及在任意尺度上计算导数,我们可以使用高斯导数滤波器 。处理方法如下。
代码:

# -*- coding: utf-8 -*-
from PIL import Image
from pylab import *
from scipy.ndimage import filters
import numpydef imx(im, sigma):imgx = zeros(im.shape)filters.gaussian_filter(im, sigma, (0, 1), imgx)return imgxdef imy(im, sigma):imgy = zeros(im.shape)filters.gaussian_filter(im, sigma, (1, 0), imgy)return imgydef mag(im, sigma):imgmag = 255 - numpy.sqrt(imgx ** 2 + imgy ** 2)return imgmagim = array(Image.open('JMU3.jpg').convert('L'))
figure()
gray()sigma = [2, 5, 10]for i in  sigma:subplot(3, 4, 4*(sigma.index(i))+1)axis('off')imshow(im)imgx=imx(im, i)subplot(3, 4, 4*(sigma.index(i))+2)axis('off')imshow(imgx)imgy=imy(im, i)subplot(3, 4, 4*(sigma.index(i))+3)axis('off')imshow(imgy)imgmag=mag(im, i)subplot(3, 4, 4*(sigma.index(i))+4)axis('off')imshow(imgmag)show()

结果:

1.4.3形态学:对象计数

    形态学(或数学形态学)是度量和分析基本形状的图像处理方法的基本框架与集合。 形态学通常用于处理二值图像,但是也能够用于灰度图像。二值图像是指图像的每 个像素只能取两个值,通常是 0 和 1。二值图像通常是,在计算物体的数目,或者度量其大小时,对一幅图像进行阈值化后的结果。
代码:

from PIL import Image
from scipy.ndimage import measurements, morphology
from pylab import *"""   This is the morphology counting objects example in Section 1.4.  """# 添加中文字体支持
from matplotlib.font_manager import FontProperties
font = FontProperties(fname=r"c:\windows\fonts\SimSun.ttc", size=14)figure()
gray()
im = array(Image.open('JMU2.jpg').convert('L'))
subplot(221)
imshow(im)
axis('off')
title(u'(a)原始二值图像', fontproperties=font)
im = (im < 128)labels, nbr_objects = measurements.label(im)
print("Number of objects:", nbr_objects)
subplot(222)
imshow(labels)
axis('off')
title(u'(b)原始图像的标签图像', fontproperties=font)im_open = morphology.binary_opening(im, ones((9, 5)), iterations=2)
subplot(223)
imshow(im_open)
axis('off')
title(u'(c)开操作后的二值图像', fontproperties=font)labels_open, nbr_objects_open = measurements.label(im_open)
print("Number of objects:", nbr_objects_open)
subplot(224)
imshow(labels_open)
axis('off')
title(u'(d)开操作后图像的标签图像', fontproperties=font)show()

结果:


分析:
    通过阈值化方式来确保该图像是二值图像。通过和 1 相乘,脚本将布尔数组转换成二进制表示。然后,我们使用 label()函数寻找单个的物体,并且按照它们属于哪个对象将整数标签给像素赋值。

1.5总结

    本章讲解了操作和处理图像的基础知识,这些知识在《数字图像处理》课程中已经多次使用过了。现在又通过实验对这些知识更进一步学习了。

Python计算机视觉编程 第一章 基本的图像操作和处理相关推荐

  1. Python计算机视觉编程第一章 基本的图像操作与处理

    基本的图像操作与处理 一.基本介绍 1.1PIL:Python图像处理类库 1.2Matplotlib 1.3Numpy 1.4Scipy 二.例子练习 2.1PIL基础操作 2.1.1 转换图像格式 ...

  2. Python计算机视觉编程 第一章——基本的图像操作和处理

    目录 1.1 PIL:Python图像处理类库 1.1.1 转换图像格式 1.1.2 创建缩略图 1.1.3 复制和粘贴图像区域 1.1.4 调整尺寸和旋转 1.2 Matplotlib 1.2.1 ...

  3. python计算机视觉编程——第一章(基本的图像操作和处理)

    第1章 基本的图像操作和处理 1.1 PIL:Python图像处理类库 1.1.1 转换图像格式--save()函数 1.1.2 创建缩略图 1.1.3 复制并粘贴图像区域 1.1.4 调整尺寸和旋转 ...

  4. Python计算机视觉编程第九章——图像分割

    Python计算机视觉编程 (一)图割(Graph Cut) 1.1 从图像创建图 1.2 用户交互式分割 (二)利用聚类进行分割 (三)变分法 (一)图割(Graph Cut) 图论中的图(grap ...

  5. Python计算机视觉编程第二章——局部图像描述子

    Python计算机视觉编程 局部图像描述子 (一)Harris 角点检测器 (二)SIFT(尺度不变特征变换) 2.1 兴趣点 2.2 描述子 2.3 检测兴趣点 2.4 匹配描述子 (三)匹配地理标 ...

  6. Python计算机视觉:第一章 图像处理基础

    第一章 图像处理基础 1.1 PIL-Python图像库 1.1.1 对图片进行格式转换 1.1.2 创建缩略图 1.1.3 拷贝并粘贴区域 1.1.4 调整尺寸及旋转 1.2 Matplotlib库 ...

  7. Python通用编程 - 第一章:用户交互

    本文是Python通用编程系列教程,已全部更新完成,实现的目标是从零基础开始到精通Python编程语言.本教程不是对Python的内容进行泛泛而谈,而是精细化,深入化的讲解,共5个阶段,25章内容.所 ...

  8. python高性能编程第一章读书笔记

    计算机底层组件分为三大基本部分:计算单元.存储单元以及两者之间的连接. 计算单元:具有将接收到的任意输入转换成输出的能力以及改变当前处理状态的能力.CPU是最常见的计算单元.它的主要属性是其每个周期能 ...

  9. python计算机视觉编程——基本的图像操作和处理

    python计算机视觉编程--第一章(基本的图像操作和处理) 第1章 基本的图像操作和处理 1.1 PIL:Python图像处理类库 1.1.1 转换图像格式--save()函数 1.1.2 创建缩略 ...

最新文章

  1. java程序猿必读的学习书籍,良心推荐!
  2. Adaboost 算法的原理与推导
  3. 关于Nginx的使用
  4. java自学难点_java学习重难点
  5. 怎样创建两个菜单JAVA_java – 如何创建一个菜单的JButton?
  6. 经典逻辑编程题(本文用python实现)
  7. 如何更好的组织你的Laravel模型 1
  8. 动态扩容Linux根目录 (解决/dev/mapper/centos-root 占用了过高问题)
  9. 微信分享#后面被截断,导致安卓分享失效
  10. matlab中怎样提取结构体下的数据库,MATLAB如何提取结构体中数据
  11. vue 生成二维码(中间logo),下载二维码,复制链接(vue + vue-qr+clipboard)
  12. android 驱动开发教程,Android驱动开发入门
  13. Python:字符宽度相同的字体(等宽字体)
  14. html5文档加载前调用函数,html调用javascript外部文件显示函数未定义
  15. NLP入门(七)中文预处理之繁简体转换及获取拼音
  16. 按键精灵通过抓抓工具来获取坐标位置
  17. 金蟾论金:4.13黄金探底回升收复跌势、晚间黄金走势分析指导
  18. 现代密码学实验5 数字签名ElGamal签名方案
  19. seo搜索引擎优化,seo搜索引擎优化名词解释
  20. mc启动器需要用的java_我的世界启动器安装使用教程图文详解

热门文章

  1. structs2-StrutsPrepareAndExecuteFilter类的理解
  2. Spring依赖注入提示:Field injection is not recommended
  3. RAC+DG架构部署(使用备份集)
  4. NRF24L01快速上手
  5. 王学岗————FFmpeg软解之视频播放(对应第39、第41、第42)
  6. 【图形基础篇】04 # GPU与渲染管线:如何用WebGL绘制最简单的几何图形?
  7. 【干货】使用Java发送各种格式的邮件
  8. 电脑硬盘坏道如何屏蔽
  9. 中职计算机老师个人月总结范文,2018年度中等专业学校计算机班主任老师工作总结范文...
  10. 医药生物行业深度报告:医药高端制造系列报告一,中国制造崛起,特色原料药受益显著(20210103).PDF