第二章-----图像基础
1.图像处理的主要步骤是什么?
①读取图片。这个过程通常涉及一些功能,以便您可以从不同的
来源(相机、视频流、磁盘、在线资源)读取图像;
②通过应用图像处理技术处理图像(阈值处理,图像混合、平滑图像、边缘检测、轮廓提取等待),实现所需的功能
③显示处理步骤的结果
2.图像三个处理级别是什么?
Low-level process
低层处理:通常以图像作为输入,输出图像。包括以下内容:噪声消除 、图像锐化、光照归一化、 透视校正
Mid-level process
中间层处理:采用预处理后的图像来输出图像的某种表示形式。
High-level process
高级层获取数字向量,通常称为属性,并输出最终结果。
3.灰度图像与黑白图像的区别是什么?
黑白图像:就只有黑色和白色,不存在过渡性的灰色,它一个像素只需要一个二进制位就能表示出来,即0表示黑,1表示白。
灰度图像:灰度图是有级数的,出了黑与白之外,还有中间过渡的灰色,用来更加精细地表示明暗变化,一般我们电脑上用的灰度图是8位,256级灰度,即用8个二进制位(1字节)来表示一个灰度图的像素。
4.像素是什么?
像素是指基本原色素及其灰度的基本编码。像素是构成数码影像的基本单元,通常以像素每英寸PPI(pixels per inch)为单位来表示影像分辨率的大小。
5.图像分辨率是什么?
指图像中存储的信息量,是每英寸图像内有多少个像素点,分辨率的单位为PPI(Pixels Per Inch),通常叫做:像素每英寸。
6.使用什么OpenCV函数来执行以下操作?
加载(读取)一个图像 ------img = cv2.imread(“读取的文件名字”,0) 0代表以灰度读入
显示图像 ---cv2.imshow(“窗口的名字”,前面加载图像给它取的名字如前面的img)
等待按键 cv2.waitkey(0) 代表程序会无限制的等待用户的按键事情;
拆分通道 ---(b, g, r) = cv2.split(img)
合并通道 ----Img = cv2.merge((b, g, r))
8. 由下列三原色得到什么颜色?
B = 0,G = 255,R=255 -------> 黄色
B = 255,G = 255,R=0 -------> 青色
B = 255,G = 0,R=255 -------> 紫色
B = 255,G = 255,R=255 -------> 白色
9.假设已经在img中加载图像。如何检查img是彩色的还是灰度的
Print(img.shape) 输出(height,width)只有两个参数 代表这是灰度图
输入 (height,width,3) 3代表这是3通道图像 即彩色图
前面所说的:height,width 指的是图片的高度和宽度
第三章---文件和图像处理
1.sys.argv[1]是什么?
列表的第二个元素sys.argv[1]是脚本的第一个参数
2.编写代码,添加int类型的first_number参数,并含有parser.add_argument()添加的第 一个帮助号。
parser.add_argument("first_number", help="first number to be added", type=int)
3.编写代码,将图像img保存到磁盘,命名为image.png。。
import cv2 img = cv2.imread('img.jpg', 1) cv2.namedWindow('picture', cv2.WINDOW_NORMAL) # 此句可以调整图片的窗口 cv2.imshow('picture.jpg', img) cv2.waitKey(0) s = input("按s保存,其他不保存") if s == "s": cv2.imwrite('image.png', img)
4.使用cv2.VideoCapture()创建捕获对象,从连接到计算机的第一个摄像头读取数据。
5包含了4看5即可
5.使用cv2.VideoCapture()创建对象捕捉,从连接到计算机的第一个摄像头读取,并打印 CAP_PROP_FRAME_WIDTH属性。
import cv2 # 打开摄像头并灰度化显示 capture = cv2.VideoCapture(0) # 获取捕获的分辨率 # capture.get返回的是VideoCaptureProperties中的属性标识符 # 属性标识符可以直接写数字,也可以用openCV符号表示 数字可以参考 “ VideoCaptureProperties ”文档 width = capture.get(cv2.CAP_PROP_FRAME_WIDTH) print(width) while True: # 获取一帧 若捕获到帧数,ret返回True ret, frame = capture.read() # 将这帧转换为灰度图 gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) cv2.imshow('frame', gray) if cv2.waitKey(1) == ord('q'): break
5.读取图像并将以同名加_copy的文件名保存到硬盘,如logo_copy.png。
同3类似
6.编写脚本(read_video_file_backwards_save_video.py),加载一个视频文件并向后播放,先播放视频最后帧,以此类推。
第四章---基本图形
1.绘制填充形状,例如,圆形或矩形,应配置哪个参数?
画圆
cv2.circle( img, center, radius, color, thickness=None, lineType=None)
参数解释:
Center:(圆心坐标) radius:半径长度 color:(圆的颜色)
-1是线宽 这里表示填充
画矩形
cv2.rectangle(img, pt1, pt2, color, thickness=None, lineType=None)
参数解释:
Img:图片, pt1:(左上角坐标), pt2:(右下角坐标), color:(线条颜色),lineType: 线宽
2.绘制反锯齿的线型,应配置哪个参数?
配置lineType。在第5个参数中输入:lineType=cv2.LINE_AA
3.绘制一条从(0,0)到(512,512)的对角线。
Import cv2
Import numpy as np
img = np.zeros((512, 512, 3), np.uint8)
# 画一条线宽为5的蓝色直线,参数2和3分别为起点和终点坐标
cv2.line(img, (0, 0), (512, 512), (255, 0, 0), 5)
cv2.imshow('img', img)
cv2.waitkey(0)
4.用所需的参数绘制“Hello OpenCV”。
# # 定义200*500的黑色背景图
img = np.zeros((200, 500, 3), np.uint8)
# 添加文字,使用cv2.putText()函数
# 设置字体
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(img, 'Hello Opencv', (50, 50), font,
2, (255, 255, 0), 2, lineType=cv2.LINE_AA)
cv2.imshow('img', img)
cv2.waitKey(0)
5. 用12个点画一个多边形,形状为圆形。
7.用鼠标事件和Matplotlib事件在双击时绘制矩形。
start, end = (0, 0), (0, 0) drawing = False def mouse_event(event, x, y, flags, param): global start, drawing, end, temp # 鼠标按下,开始画图:记录下起点 if event == cv2.EVENT_LBUTTONDOWN: drawing = True start = (x, y) # 实时移动的位置作为矩形终点(右下角点) elif event == cv2.EVENT_MOUSEMOVE: if drawing: # 若没有drawing这个参数,只要我们移动鼠标还会持续不断画圆 end = (x, y) # 鼠标释放后,停止绘图,同时drawing 设置为False,目的是让上一步移动鼠标事件后续动作不执行 elif event == cv2.EVENT_LBUTTONUP: drawing = False cv2.rectangle(img, start, (x, y), (0, 255, 0), 2) start = end = (0, 0) img = np.zeros((512, 512, 3), np.uint8) start, end = (0, 0), (0, 0) drawing = False def mouse_event(event, x, y, flags, param): global start, drawing, end, temp # 鼠标按下,开始画图:记录下起点 if event == cv2.EVENT_LBUTTONDOWN: drawing = True start = (x, y) # 实时移动的位置作为矩形终点(右下角点) elif event == cv2.EVENT_MOUSEMOVE: if drawing: # 若没有drawing这个参数,只要我们移动鼠标还会持续不断画圆 end = (x, y) # 鼠标释放后,停止绘图,同时drawing 设置为False,目的是让上一步移动鼠标事件后续动作不执行 elif event == cv2.EVENT_LBUTTONUP: drawing = False cv2.rectangle(img, start, (x, y), (0, 255, 0), 2) start = end = (0, 0) img = np.zeros((512, 512, 3), np.uint8)
第五章---图像处理技术
1.哪个函数将一个多通道分割成多个单通道图像?
(b,g,r) = cv2.split(img)
2.哪个函数将多个单通道图像合并成一个多通道图像?
img1 = cv2.merge(b, g, r)
3. 在x方向上平移150像素,在y方向上平移300像素。
height, width = image.shape[:2]M = np.float32([[1, 0, 150], [0, 1, 150]]) #平移矩阵2x3dst_image = cv2.warpAffine(image, M, (width, height))
5.将名为img的图像相对于图像中心旋转30度,比例系数为1。
height, width = image.shape[:2] M = cv2.getRotationMatrix2D((width/2.0, height / 2.0), 30, 1)#旋转矩阵 dst_image = cv2.warpAffine(image, M, (width, height))
6.构建一个5 x 5的平均内核,并使用cv2.filter2D()将其应用于图像。
kernel_averaging_5_5 = np.ones((5, 5), np.float32)/25 smooth_image_f2D = cv2.filter2D(image, -1, kernel_averaging_5_5)
7.将灰度图像中的所有像素加40。
scalar = np.ones(image.shape , dtype="float") * 40added_image_2 = cv2.add(image, scalar)
7. 将COLORMAP_JET颜色映射应用于灰度图像。
img_COLORMAP_HSV = cv2.applyColorMap(gray_img, cv2.COLORMAP_JET)
第六章----直方图构建
1.什么是图像直方图?
图像直方图是一种反映图像色调分布的直方图,描述每个色调值的像素数量。每个色调值的像素数也称为频率。因此,强度值在[0,K-1] 范围内的灰度图像的直方图将恰好包含K个数量。
直方图显示图像数据时会以左暗又亮的分布曲线形式呈现出来,而不是显示原图像数据,并且可以通过算法来对图像进行按比例缩小,且具有图像平移、旋转、缩放不变性等众多优点。直方图在进行图像计算处理时代价较小,所以经常用于图像处理!
2.用64 bins计算灰度图像的直方图。
img = cv2.imread('读取的图片') gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) hist = cv2.calcHist([gray_img], [0], None, [64], [0, 256])
3.将灰度图像上的每个像素加50,图像看起来更亮,计算直方图。
array = np.ones(gray_img.shape, np.uint8) * 50 result = cv2.add(gray_img, array) hist_result= cv2.calcHist([result], [0], None, [256],[0, 256])
4.计算没有掩码的BGR图像的红色通道直方图。
img_red = cv2.calcHist([img], [2], None, [256], [0, 256]) 第二个参数「0」代表B即蓝色 「1」代表G即绿色
5.OpenCV、NumPy和Matplotlib提供了什么函数来计算直方图?
1.opencv中
使用cv2.calcHist(images, channels, mask, histSize, ranges)计算,其中:
参数1:要计算的原图,以方括号的传入,如:[img]
参数2:类似前面提到的dims,灰度图写[0]就行,彩色图B/G/R分别传入[0]/[1]/[2]
参数3:是指要计算的区域(mask:目标区域白色,其余黑色),计算整幅图的话,写None
如果需要对图片某块区域进行直方图计算可以用如下方法
mask = np.zero(img.shape, np.uint8)
mask[y0:y1, x0:x1] = 255 再把mask 传入上述第三个参数即可实现某块区域的直方图计算
参数4:子区段数目,如果我们统计0~255每个像素值,bins=256;如果划分区间,比如0~15, 16~31…240~255
这样16个区间,bins=16
参数5:要计算的像素值范围,一般为[0,256)
2.numpy中有两个
hist, bins = np.histogram(img.ravel(), 256, [0, 256]) hist = np.bincount(img.ravel(), minlength=256) ---其实ravel()函数是将二维矩阵展平变成一维数组
3.matplotlib中
plt.hist(img.ravel(), 256, [0, 256]) plt.show()
6.修改grayscale_histogram.py脚本,计算这三个图像
(gray_image、added_image和subtracted_image)的亮度。将脚本重
命名为grayscale_histogram_brightness.py。
7.修改comparing_hist_equalization_clahe.py脚本,以显示
cv2.equalizeHist()和CLAHE的执行时间。将其重命名为
comparing_hist_equalization_clahe_time.py。
第七章--阈值技术
固定阈值分割
cv2.threshold(src, thresh, maxval, type)用来实现阈值分割,ret是return value缩写,代表当前的阈值.
函数有4个参数:
*参数src:要处理的原图,一般是灰度图
*参数thresh:设定的阈值
*参数maxval:最大阈值,一般为255
*参数type:阈值的方式,主要有5种
自适应阈值:
cv2.adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C)
*参数1src:要处理的原图
*参数2maxValue:最大阈值,一般为255
*参数3adaptiveMethod:小区域阈值的计算方式
ADAPTIVE_THRESH_MEAN_C:小区域内取均值 ADAPTIVE_THRESH_GAUSSIAN_C:小区域内加权求和,权重是个高斯核
*参数thresholdType:阈值方式(跟前面讲固定阈值的那5种相同)
*参数blockSize:小区域的面积,如11就是11*11的小块
*参数C:最终阈值等于小区域计算出的阈值再减去此值
1.使用cv2.threshold()应用阈值操作,阈值值为100,并使用cv2。THRESH_BINARY阈值类型。
img = cv2.imread(“读取的图片”) ret, th1 = cv2.threshold(img, 100, 255, cv2.THRESH_BINARY)
2. 使用cv2. adapativethreshold (),cv2应用自适应阈值设定操作。ADAPTIVE_THRESH_MEAN_C, C=2, blockSize=9。
img = cv2.imread(“读取的图片”) new_img = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 9, 2)
3.使用cv2应用Otsu的阈值设定。THRESH_BINARY阈值类型。
img = cv2.imread(“读取的图片”) ret, th = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
4. 使用cv2应用三角形阈值。THRESH_BINARY阈值类型。
img = cv2.imread(“读取的图片”) ret, th = cv2.threshold(img, 0, 255, cv2.THRESH_TRIANGLE + cv2.THRESH_BINARY)
5. 使用scikit-image应用大津的阈值设定。
6.使用scikit-image应用三角形阈值。
7. 使用scikit-image应用Niblack的阈值设定。
8. 应用Sauvola的阈值设定使用scikit-image和25的窗口大小。
9. 修改thresholding_example.py脚本,以便使用np.arange(),目的是定义应用到cv2.threshold()函数的阈值。然后,使用已定义的阈值调用cv2.threshold()函数,并将所有阈值图像存储在一个数组中。最后,为每个图像调用show_img_with_matplotlib()来显示数组中的所有图像。将脚本重命名为thresholding_example_arange.py。
第八章---轮廓检测
1.如果要检测二值图像中的轮廓,应该使用什么函数?
contours, hierarchy = findContours(image, mode,method )
参数image:指的是二值图
参数mode:轮廓的查找方式
参数method:轮廓的近似方法
2.OpenCV提供了哪四个旗子来压缩轮廓?
cv2.CHAIN_APPROX_NONEcv2.CHAIN_APPROX_SIMPLEcv2.CHAIN_APPROX_TC89_L1cv2.CHAIN_APPROX_TC89_KCOS
3.OpenCV提供了什么功能来计算图像矩?
M = cv2.moments(cnt)----此处cnt指之前findContours找到的轮廓
4.什么力矩提供了轮廓的大小?
图像矩
5.OpenCV提供了什么函数来计算7个Hu矩不变量?
hu = HuMoments(m) ---其中m指的是是由函数m = cv2.moments(cnt)计算得到矩特征值。
6.如果想要得到给定轮廓的轮廓近似值,应该使用什么函数?
cv2.findContours() ---以下是代码实现
**** 为了简洁 读取灰度图和那个显示图片步骤省略
ret,thresh=cv2.threshold(img,0,255,cv2.THRESH_BINARY + cv2.THRESH_OTSU) contours, hierarchy = cv2.findContours(thresh, 3, 2)cnt = contours[0]
# 2.进行多边形逼近,得到多边形的角点
approx = cv2.approxPolyDP(cnt, 40, True)
img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR) cv2.polylines(img, [approx], True, (0, 255, 0), 2)
7.在contour_function.py脚本中定义的extreme_points()函数用更紧凑的方式重写。
8.如果想用Hu矩不变量作为特征来匹配轮廓,应用什么函数
cv2.matchShapes()