题外补充
编译型语言和解释型语言的区别
我们编写的源代码是人类语言,我们自己能够轻松理解;但是对于计算机硬件(CPU),源代码就是天书,根本无法执行,计算机只能识别某些特定的二进制指令,在程序真正运行之前必须将源代码转换成二进制指令。
所谓的二进制指令,也就是机器码,是 CPU 能够识别的硬件层面的“代码”,简陋的硬件(比如古老的单片机)只能使用几十个指令,强大的硬件(PC 和智能手机)能使用成百上千个指令。
然而,究竟在什么时候将源代码转换成二进制指令呢?不同的编程语言有不同的规定:
有的编程语言要求必须提前将所有源代码一次性转换成二进制指令,也就是生成一个可执行程序(Windows 下的 .exe),比如C语言、C++、Golang、Pascal(Delphi)、汇编等,这种编程语言称为编译型语言,使用的转换工具称为编译器。
有的编程语言可以一边执行一边转换,需要哪些源代码就转换哪些源代码,不会生成可执行程序,比如 Python、JavaScript、PHP、Shell、MATLAB 等,这种编程语言称为解释型语言,使用的转换工具称为解释器。
详细文章链接:http://c.biancheng.net/view/4136.html
图像位运算
btwise_and(), bitwise_or(), bitwise_not(), bitwise_xor()
cv2.btwise_and(): 与运算
参数:
img1:图片对象1
img2:图片对象2
mask:掩膜
cv2.bitwise_or():或运算
参数:
img1:图片对象1
img2:图片对象2
mask:掩膜
cv2.bitwise_not(): 非运算
img1:图片对象1
mask:掩膜
cv2.bitwise_xor():异或运算,相同为1,不同为0(1^1=0,1^0=1)
img1:图片对象1
img2:图片对象2
mask:掩膜
掩膜
在有些图像处理的函数中有的参数里面会有mask参数,即此函数支持掩膜操作,首先何为掩膜以及有什么用,如下:
数字图像处理中的掩膜的概念是借鉴于PCB制版的过程,在半导体制造中,许多芯片工艺步骤采用光刻技术,用于这些步骤的图形“底片”称为掩膜(也称作“掩模”),其作用是:在硅片上选定的区域中对一个不透明的图形模板遮盖,继而下面的腐蚀或扩散将只影响选定的区域以外的区域。
图像掩膜与其类似,用选定的图像、图形或物体,对处理的图像(全部或局部)进行遮挡,来控制图像处理的区域或处理过程。
数字图像处理中,掩模为二维矩阵数组,有时也用多值图像,图像掩模主要用于:
①提取感兴趣区,用预先制作的感兴趣区掩模与待处理图像相乘,得到感兴趣区图像,感兴趣区内图像值保持不变,而区外图像值都为0。
②屏蔽作用,用掩模对图像上某些区域作屏蔽,使其不参加处理或不参加处理参数的计算,或仅对屏蔽区作处理或统计。
③结构特征提取,用相似性变量或图像匹配方法检测和提取图像中与掩模相似的结构特征。
④特殊形状图像的制作。
图像颜色空间转换
cv2.cvtColor()
cv2.cvtColor()
参数:
img: 图像对象
code:
cv2.COLOR_RGB2GRAY: RGB转换到灰度模式
cv2.COLOR_RGB2HSV: RGB转换到HSV模式(hue,saturation,Value)
cv2.inRange()
参数:
img: 图像对象/array
lowerb: 低边界array, 如lower_blue = np.array([110,50,50])
upperb:高边界array, 如 upper_blue = np.array([130,255,255])
mask = cv2.inRange(hsv, lower_green, upper_green)
性能评价
cv2.getTickCount(): 获得时钟次数
cv2.getTickFrequency():获得时钟频率 (每秒振动次数)
img1 = cv2.imread('messi5.jpg')
e1 = cv2.getTickCount()
for i in xrange(5,49,2):
img1 = cv2.medianBlur(img1,i)
e2 = cv2.getTickCount()
t = (e2 - e1)/cv2.getTickFrequency()
print t
绑定trackbar到图像
cv2.createTrackbar()
cv2.getTrackbarPos()
cv2.createTrackbar() 为窗口添加trackbar
参数:
trackbarname: trackbar的名字
winname: 窗口的名字
value: trackbar创建时的值
count:trackbar能设置的最大值,最小值总为0
onChange:trackbar值发生变化时的回调函数,trackbar的值作为参数传给onchange
cv2.getTrackbarPos() 获取某个窗口中trackbar的值
参数:
trackbarname: trackbar的名字
winname: 窗口的名字
图像阈值化
cv2.threshold()
cv2.adaptiveThreshold()
cv2.threshold():
参数:
img:图像对象,必须是灰度图
thresh:阈值
maxval:最大值
type:
cv2.THRESH_BINARY: 小于阈值的像素置为0,大于阈值的置为maxval
cv2.THRESH_BINARY_INV: 小于阈值的像素置为maxval,大于阈值的置为0
cv2.THRESH_TRUNC: 小于阈值的像素不变,大于阈值的置为thresh
cv2.THRESH_TOZERO 小于阈值的像素置0,大于阈值的不变
cv2.THRESH_TOZERO_INV 小于阈值的不变,大于阈值的像素置0
返回两个值
ret:阈值
img:阈值化处理后的图像
cv2.adaptiveThreshold() 自适应阈值处理,图像不同部位采用不同的阈值进行处理
参数:
img: 图像对象,8-bit单通道图
maxValue:最大值
adaptiveMethod: 自适应方法
cv2.ADAPTIVE_THRESH_MEAN_C :阈值为周围像素的平均值
cv2.ADAPTIVE_THRESH_GAUSSIAN_C : 阈值为周围像素的高斯均值(按权重)
threshType:
cv2.THRESH_BINARY: 小于阈值的像素置为0,大于阈值的置为maxValuel
cv2.THRESH_BINARY_INV: 小于阈值的像素置为maxValue,大于阈值的置为0
blocksize: 计算阈值时,自适应的窗口大小,必须为奇数 (如3:表示附近3个像素范围内的像素点,进行计算阈值)
C: 常数值,通过自适应方法计算的值,减去该常数值
(mean value of the blocksize*blocksize neighborhood of (x, y) minus C)
阈值处理
一幅图像包括目标物体、背景还有噪声,要想从多值的数字图像中直接提取出目标物体,常用的方法就是设定一个阈值T,用T将图像的数据分成两部分:大于T的像素群和小于T的像素群。这是研究灰度变换的最特殊的方法,称为图像的二值化(Binarization)。
阈值分割法的特点是:适用于目标与背景灰度有较强对比的情况,重要的是背景或物体的灰度比较单一,而且总可以得到封闭且连通区域的边界。
今日代码实例总结
将logo图片移动到图片中,需要截取logo图片的前景和图片ROI的背景,然后叠加:
import cv2 as cv
import matplotlib.pyplot as plt
img1 = cv.imread(r"D:\Q2020-07-22211309.png")#读取第一个图片
rows,cols = img1.shape[0:2] #imread返回值类型为(高度,宽度,通道数)的元组
img2 = cv.imread(r"D:\QQ20200323120857.jpg")
roi = img2[0:rows,0:cols] #ROI截取0行到rows行,0列到cols列的区域
img1_gray = cv.cvtColor(img1,cv.COLOR_BGR2GRAY) #颜色空间转换函数,此处是彩色转灰色
#图像阈值化,小于阈值的像素置为maxval,大于阈值的置为0
ret,img1_thres = cv.threshold(img1_gray,200,255,cv.THRESH_BINARY_INV)
img1_fg =cv.add(img1,img1,mask=img1_thres) #拿到logo图案的前景
img1_thres_inv = cv.bitwise_not(img1_thres)#图像位与运算
roi_bg = cv.add(roi,roi,mask=img1_thres_inv) #拿到roi图案的背景
img_add = cv.add(img1_fg,roi_bg) #背景和前景相加
img2[0:rows,0:cols] = img_add #将截取到的img_add移动到该区域
cv.imshow("gray",img1_gray)
cv.imshow("thres",img1_thres)
cv.imshow("fg",img1_fg)
cv.imshow("tinv",img1_thres_inv)
cv.imshow("roi_bg",roi_bg)
cv.imshow("img_add",img_add)
cv.imshow("img2",img2)
cv.waitKey(0)
cv.destroyAllWindows()
使用图片
结果