cv七
1.分水岭算法

1 # 分水岭算法 2 # 基于距离变换的分水岭分割流程 3 # 输入图像->灰度->二值化->距离变换->寻找种子->生成Marker->分水岭变换->输出图像 4 5 import cv2 as cv 6 import numpy as np 7 8 """ 9 分水岭算法原理: 10 任何一副灰度图像都可以被看成拓扑平面,灰度值高的区域可以被看成是 山峰,灰度值低的区域可以被看成是山谷。 11 我们向每一个山谷中灌不同颜色的水。随着水的位的升高,不同山谷的水就会相遇汇合,为了防止不同山谷的水 汇合, 12 我们需要在水汇合的地方构建起堤坝。不停的灌水,不停的构建堤坝知 道所有的山峰都被水淹没。 13 我们构建好的堤坝就是对图像的分割。这就是分水岭算法的背后哲理 14 但是这种方法通常都会得到过度分割的结果,这是由噪声或者图像中其他不规律的因素造成的。 15 为了减少这种影响,OpenCV 采用了基于掩模的分水岭算法,在这种算法中我们要设置那些山谷点会汇合,那些不会。 16 这是一种交互式的图像分割。我们要做的就是给我们已知的对象打上不同的标签。 17 如果某个区域肯定是前景或对象,就使用某个颜色(或灰度值)标签标记它。 18 如果某个区域肯定不是对象而是背景就使用另外一个颜色标签标记。而剩下的不能确定是前景还是背景的区域就用 0 标记。 19 这就是我们的标签。然后实施分水岭算法。 20 每一次灌水,我们的标签就会被更新,当两个不同颜色的标签相遇时就构建堤坝,直到将所有山峰淹没, 21 最后我们得到的边界对象(堤坝)的值为 -1。 22 基于距离的分水岭分割流程: 23 输入图像->灰度->二值->距离变换->寻找种子->生成marker->分水岭变换->输出图像 24 """ 25 26 27 def watershed_demo(image): 28 print(image.shape) 29 blurred = cv.pyrMeanShiftFiltering(image, 10, 100) 30 gray = cv.cvtColor(blurred, cv.COLOR_BGR2GRAY) 31 ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU) 32 cv.imshow("binary", binary) 33 34 # morphology operation 35 kernel = cv.getStructuringElement(cv.MORPH_RECT, (3, 3)) 36 opening = cv.morphologyEx(binary, cv.MORPH_OPEN, kernel=kernel, iterations=2) 37 sure_bg = cv.dilate(opening, kernel, iterations=3) 38 cv.imshow("morphology operation", sure_bg) 39 # Finding sure foreground area 40 # 距离变换的基本含义是计算一个图像中非零像素点到最近的零像素点的距离, 41 # 也就是到零像素点的最短距离 42 # 个最常见的距离变换算法就是通过连续的腐蚀操作来实现,腐蚀操作的停止条件是所有前景像素都被完全腐蚀。 43 # 这样根据腐蚀的先后顺序,我们就得到各个前景像素点到前景中心像素点的距离。 44 # 根据各个像素点的距离值,设置为不同的灰度值。这样就完成了二值图像的距离变换 45 # cv2.distanceTransform(src, distanceType, maskSize) 46 # 第二个参数 0,1,2 分别表示 CV_DIST_L1, CV_DIST_L2 , CV_DIST_C 47 dist_transform = cv.distanceTransform(opening, 1, 3) # 掩膜大小是5 48 dist_output = cv.normalize(dist_transform, 0, 1.0, cv.NORM_MINMAX) 49 cv.imshow("distance-t", dist_output*50) 50 51 ret, sure_face = cv.threshold(dist_transform, 0.6*dist_transform.max(), 255, cv.THRESH_BINARY) 52 53 # Finding unknown region 54 sure_fg = np.uint8(sure_face) # 把float类型转换成int 55 unknown = cv.subtract(sure_bg, sure_fg) 56 57 ret, markers1 =cv.connectedComponents(sure_fg) 58 print(ret) 59 60 # 分水岭变换 61 markers = markers1 + 1 62 markers[unknown == 255] = 0 63 markers3 = cv.watershed(image, markers=markers) 64 image[markers3 == -1] = [0, 0, 255] # markers被标记过的区域为-1 65 cv.imshow("result", image) 66 67 68 def main(): 69 src = cv.imread("../images/circle.png") 70 cv.imshow("demo",src) 71 watershed_demo(src) 72 cv.waitKey(0) # 等有键输入或者1000ms后自动将窗口消除,0表示只用键输入结束窗口 73 cv.destroyAllWindows() # 关闭所有窗口 74 75 76 if __name__ == '__main__': 77 main()
2.人脸检测

1 # 人脸检测 2 # HAAR与LBP数据 3 4 5 import cv2 as cv 6 7 """ 8 使用Haar分类器进行面部检测 9 1. 简单介绍Haar特征分类器对象检测技术 10 它是基于机器学习的,通过使用大量的正负样本图像训练得到一个cascade_function,最后再用它来做对象检测。 11 如果你想实现自己的面部检测分类器,需要大量的正样本图像(面部图像)和负样本图像(不含面部的图像)来训练分类器。 12 可参考https://docs.opencv.org/2.4/doc/user_guide/ug_traincascade.html,这里不做介绍,现在我们利用 13 OpenCV已经训练好的分类器,直接利用它来实现面部和眼部检测。 14 15 2. 主要步骤: 16 1)加载xml分类器,并将图像或者视频处理成灰度格式 cv.CascadeClassifier() 17 2)对灰度图像进行面部检测,返回若干个包含面部的矩形区域 Rect(x,y,w,h)face_detector.detectMultiScale() 18 3)创建一个包含面部的ROI,并在其中进行眼部检测 19 20 3. 重要方法分析:def detectMultiScale(self, image, scaleFactor=None, minNeighbors=None, minSize=None, maxSize=None) 21 原理:检测输入图像在不同尺寸下可能含有的目标对象 22 #minSize – Minimum possible object size. Objects smaller than that are ignored. 23 #maxSize – Maximum possible object size. Objects larger than that are ignored. 24 入参: 25 1)image:输入的图像 26 2)scaleFactor:比例因子,图像尺寸每次减少的比例,要大于1,这个需要自己手动调参以便获得想要的结果 27 3)minNeighbors:最小附近像素值,在每个候选框边缘最小应该保留多少个附近像素 28 4)minSize,maxSize:最小可能对象尺寸,所检测的结果小于该值会被忽略。最大可能对象尺寸,所检测的结果大于该值会被忽略 29 返回:若干个包含对象的矩形区域 30 """ 31 32 33 def face_detection(image): 34 gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY) 35 face_detector = cv.CascadeClassifier("../images/haarcascade_frontalface_alt_tree.xml") 36 eyes_detector = cv.CascadeClassifier("../images/haarcascade_eye.xml") 37 faces = face_detector.detectMultiScale(gray, 1.01, 5) 38 for x, y, w, h in faces: 39 img = cv.rectangle(image, (x, y), (x + w, y + h), (0, 0, 255), 2) 40 roi_gray = gray[y:y + h, x:x + w] 41 roi_color = img[y:y + h, x:x + w] 42 eyes = eyes_detector.detectMultiScale(roi_gray, 1.3, 5) 43 44 for ex, ey, ew, eh in eyes: 45 cv.rectangle(roi_color, (ex, ey), (ex + ew, ey + ey), (0, 255, 0), 2) 46 47 cv.imshow("result", image) 48 49 50 def main(): 51 src = cv.imread("../images/CrystalLiu1.jpg") 52 cv.namedWindow("input image", cv.WINDOW_AUTOSIZE) 53 54 cv.imshow("input image", src) 55 face_detection(src) 56 57 # 打开摄像头进行视频检测 58 # capture = cv.VideoCapture(0) 59 # cv.namedWindow("result", cv.WINDOW_AUTOSIZE) 60 # while True: 61 # ret, frame = capture.read() 62 # # frame = cv.flip(frame, 0) 63 # face_detection(frame) 64 # c = cv.waitKey(10) 65 # if c == 27: 66 # break 67 68 cv.waitKey(0) 69 cv.destroyAllWindows() # 关闭所有窗口 70 71 72 if __name__ == '__main__': 73 main()
3.验证码识别

1 # 数字验证码识别 2 # opencv+Tesserct-OCR 3 4 5 import cv2 as cv 6 import numpy as np 7 from PIL import Image 8 import pytesseract as tess 9 10 """ 11 验证码识别 12 1.步骤: 13 1. 预处理-去除干扰线和点 14 2.不同的结构元素中选择 15 3. Image和numpy array相互转换 16 4. 识别和输出 tess.image_to_string 17 2. 报错与处理 18 当出现该错误:raise TesseractNotFoundError() pytesseract.pytesseract.TesseractNotFoundError: tesseract is not installed or it's not in your path 19 不同系统采用不同策略: 20 On Linux 21 sudo apt update 22 sudo apt install tesseract-ocr 23 sudo apt install libtesseract-dev 24 On Mac 25 brew install tesseract 26 On Windows 27 先下载tesseract包:https://github.com/UB-Mannheim/tesseract/wiki. 28 然后修改pytesseract.py中tesseract_cmd指向的路径:tesseract_cmd = 'C:\\Program Files (x86)\\Tesseract-OCR\\tesseract.exe' 29 30 references: https://pypi.org/project/pytesseract/ (INSTALLATION section) and https://github.com/tesseract-ocr/tesseract/wiki#installation 31 """ 32 33 34 def recognition_demo(image): 35 gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY) 36 ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY_INV | cv.THRESH_OTSU) 37 cv.imshow("binary", binary) 38 39 # 如果二值化效果已经很好了,就不需要形态学处理 40 kernel = cv.getStructuringElement(cv.MORPH_RECT, (1, 2)) 41 bin1 = cv.morphologyEx(binary, cv.MORPH_OPEN, kernel=kernel) # 去掉干扰性直线 42 kernel = cv.getStructuringElement(cv.MORPH_RECT, (1, 2)) 43 openout = cv.morphologyEx(bin1, cv.MORPH_OPEN, kernel=kernel) # 去掉干扰性直线 44 cv.imshow("binary-image", openout) 45 46 cv.bitwise_not(openout) # 变换背景 47 textImage = Image.fromarray(openout) 48 text = tess.image_to_string(textImage) 49 50 print("识别结果:", text) 51 52 53 def main(): 54 src = cv.imread("../images/yzm.jpg") 55 cv.imshow("demo", src) 56 recognition_demo(src) 57 cv.waitKey(0) # 等有键输入或者1000ms后自动将窗口消除,0表示只用键输入结束窗口 58 cv.destroyAllWindows() # 关闭所有窗口 59 60 61 if __name__ == '__main__': 62 main()