[TOC]
OpenCV -API (python)
APi Tutorials imgproc 模块. 图像处理 OpenCV 2.3.2 documentation
一、Image I/O imread imsave imshow() resize cv2.resize的第二个参数dim是(W, H)
1 cv2.resize(array, (W, H))
copyMakeBorder cv2.copyMakeBorder的第二个到第五个参数是top, bottom, left, right,是先H后W
opencv中以左上角为原点,W方向为x,H方向为y
1 def copyMakeBorder (src, top, bottom, left, right, borderType, dst=None , value=None ):
**扩充src的边缘,将图像变大,**然后以各种外插方式自动填充图像边界,这个函数实际上调用了函数cv::borderInterpolate,这个函数最重要的功能就是为了处理边界,比如均值滤波或者中值滤波中,使用copyMakeBorder将原图稍微放大,然后我们就可以处理边界的情况了
CV demo {实现crop,pad) 使用opencv-python 对图像进行resize和填充 在图像输入神经网络之前,需要进行一定的处理,假设神经网络的图像输入是256 256然后进行了224 224的random crop。
我们需要进行如下处理:
读入原始图像
1 image = cv2.imread("img.jpg" )
截取图像中有价值的部分
1 region = image[y1:y2, x1:x2]
确定图片的长边和短边,然后把长边resize到224,保持纵横比的情况下resize短边
1 2 3 4 5 6 w, h = x2 - x1, y2 - y1 m = max (w, h) ratio = 224.0 / m new_w, new_h = int (ratio * w), int (ratio *h) assert new_w > 0 and new_h > 0 resized = cv2.resize(region, (new_w, new_h))
把图片进行填充,填充到256 256
1 2 3 4 5 6 7 8 9 10 11 12 W, H = 256 , 256 top = (H - new_h) // 2 bottom = (H - new_h) // 2 if top + bottom + h < H: bottom += 1 left = (W - new_w) // 2 right = (W - new_w) // 2 if left + right + w < W: right += 1 pad_image = cv2.copyMakeBorder(resized, top, bottom, left, right, cv2.BORDER_CONSTANT, value = self .white)
图片在输入网络之后,训练的时候进行random crop,就会发生有一部分被截取掉的情况,而这正是我们想要的图像增强 在test阶段,是进行centre crop,而正好把整个图像都截取出来,而这正是我们想要的 值得注意的是,image.shape,cv2.resize和cv2.copyMakeBorder几个函数
image.shape的输出是(H, W, C)
三、形态变化
形态变化是基于图像中物体的形态进行一些简单变换,通常在二值化的图像上进行,
1.侵蚀 侵蚀的基本思想就像土壤侵蚀一样,侵蚀着物体前景色(白色)的边界。形态学处理内核在图像窗口中滑动,只有当内核下的所有像素都为1时,原始图像中的像素(1或0)才会被视为1,否则它将被侵蚀(变为零)。我要说话
因此最终的表现就是,所有靠近前景色边界的像素都将而被丢弃,内核尺寸越大丢的越多,即白色的区域会减小。这种操作对于消除小的白色噪声(如我们在色彩空间一章中所看到的)、分离两个连接的对象等非常有用。
1 2 3 4 5 6 7 8 9 10 11 def pltShow (img ): dst = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) plt.imshow(dst) def testErosion (): img = cv2.imread('test.png' , 0 ) kernel = np.ones((5 , 5 ), np.uint8) erosion = cv2.erode(img, kernel, iterations=1 ) plt.subplot(121 ),pltShow(img),plt.title("Origin" ) plt.subplot(122 ),pltShow(erosion),plt.title("Erosion" ) plt.show()
2.膨胀 膨胀的效果正好与侵蚀相反,如果内核下至少有一个像素为“1”,则像素元素为“1”。因此,它增加了图像中的白色区域(前景对象)的大小。我要说话
在去除噪音的时候,一般采用的操作是侵蚀之后再膨胀。侵蚀消除了白色的噪音,但它也缩小了物体,所以需要通过膨胀来还原。而噪音已经在侵蚀的过程中消失,膨胀的时候也不会再出现。例子:
1 2 img_3 = cv2.imread(img_path, mode) erosion = cv2.dilate(img_3, kernel, iterations=1 )
3 开运算 开运算就是2节中讲到的先侵蚀再膨胀的操作,可以认为是个语法糖吧。(外部杂点去除)
1 2 3 4 5 6 7 8 9 10 def testOpen (): img = cv2.imread("test2.png" , 0 ) kernel = np.ones((5 ,5 ), np.uint8) erosion = cv2.erode(img, kernel, iterations=1 ) dilateAfterErosion = cv2.dilate(erosion, kernel, iterations=1 ) opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel) plt.subplot(131 ), pltShow(img), plt.title("Origin" ) plt.subplot(132 ), pltShow(dilateAfterErosion), plt.title("DilateAfterErosion" ) plt.subplot(133 ), pltShow(opening), plt.title("Opening" ) plt.show()
4 闭运算 顾名思义,开运算与闭运算是相反的语法糖——先膨胀再侵蚀,其作用也可以想象到了,可以填充上物体内部的杂点。
1 2 3 4 5 6 7 8 9 10 def testClose (): img = cv2.imread("test3.png" , 0 ) kernel = np.ones((5 ,5 ), np.uint8) dilate = cv2.dilate(img, kernel, iterations=1 ) erosionAfterDilate = cv2.erode(dilate, kernel, iterations=1 ) closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel) plt.subplot(131 ), pltShow(img), plt.title("Origin" ) plt.subplot(132 ), pltShow(erosionAfterDilate), plt.title("ErosionAfterDilate" ) plt.subplot(133 ), pltShow(closing), plt.title("Closing" ) plt.show()
5.形态梯度 出现梯度变化的地方前景色保留,其它的去掉,用于检测边缘
1 2 3 4 5 6 7 def testGradient (): img = cv2.imread('test.png' , 0 ) kernel = np.ones((2 , 2 ), np.uint8) gradient = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel) plt.subplot(121 ), pltShow(img), plt.title("Origin" ) plt.subplot(122 ), pltShow(gradient), plt.title("Gradient" ) plt.show()
6.tophat 顶帽 = 原图 - 开运算
开运算的效果是去除图像外的噪点,因此原图 - 开运算就得到了去掉的噪点 。
通过API — morphologyEx (img, MORPH_TOPHAT , kernel)
1 2 3 4 5 6 7 8 9 10 import cv2import numpy as npcv2.namedWindow("img" , cv2.WINDOW_NORMAL) cv2.resizeWindow("img" , 640 , 480 ) img = cv2.imread("i.png" ) kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3 , 3 )) new_img = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel, iterations=1 ) cv2.imshow("img" , np.hstack((img, new_img))) cv2.waitKey(0 ) cv2.destroyAllWindows()
7. blackhat 黑帽 = 原图 - 闭运算
闭运算可以将图形内部的噪声点去掉,那么原图 - 闭运算的结果就是图形内部的噪声点 。
通过API — morphologyEx(img, MORPH_BLACKHAT, kernel)
1 2 3 4 5 6 7 8 9 10 11 import cv2import numpy as npcv2.namedWindow("img" , cv2.WINDOW_NORMAL) cv2.resizeWindow("img" , 640 , 480 ) img = cv2.imread("is.png" ) kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3 , 3 )) new_img = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel, iterations=1 ) cv2.imshow("img" , np.hstack((img, new_img))) cv2.waitKey(0 ) cv2.destroyAllWindows()
8. 自定义内核 四、图像处理 图像金字塔 图像阈值操作 五、仿射变换
1 2 warp_mat = getAffineTransform( srcTri, dstTri ); warpAffine( src, warp_dst, warp_mat, warp_dst.size() );
rotation 1 2 rot_mat = getRotationMatrix2D( center, angle, scale ); warpAffine( warp_dst, warp_rotate_dst, rot_mat, warp_dst.size() );
轮廓 rectangle & boundingRect
然后利用cv2.rectangle(img, (x,y), (x+w,y+h), (0,255,0), 2)
画出矩行
1 2 3 4 5 6 参数解释 第一个参数:img是原图 第二个参数:(x,y)是矩阵的左上点坐标 第三个参数:(x+w,y+h)是矩阵的右下点坐标 第四个参数:(0,255,0)是画线对应的rgb颜色 第五个参数:2是所画的线的宽度
1 2 3 4 5 6 7 8 9 10 x, y, w, h = cv2.boundingRect(cnt) cv2.rectangle(img, (x, y), (x+w, y+h), (0 , 255 , 0 ), 2 ) rect = cv2.minAreaRect(cnt) box = cv2.cv.BoxPoints(rect) box = np.int0(box) cv2.drawContours(img, [box], 0 , (0 , 0 , 255 ), 2 ) cv2.imwrite('contours.png' , img)
七、Video api 1 2 3 4 5 6 7 8 9 10 11 12 cap = cv2.VideoCapture(0 ) cap = cv2.VideoCapture(“../test.avi”) ret,frame = cap.read() cap.release()
八、应用 Sobel导数 如何计算梯度,以及如何使用梯度来检测边缘。
Laplace算子 边缘检测算法。
Canny边缘检测 这儿是一个更高级的边缘检测算法。
霍夫线变换 霍夫变换来检测直线。
霍夫圆变换 霍夫变换来检测圆。
Remapping重映射 两副图像之间建立坐标位置的映射。
九、CV Face CascadeClassifier 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 haarcascade_eye.xml haarcascade_eye_tree_eyeglasses.xml haarcascade_frontalcatface.xml haarcascade_frontalcatface_extended.xml haarcascade_frontalface_alt.xml haarcascade_frontalface_alt2.xml haarcascade_frontalface_alt_tree.xml haarcascade_frontalface_default.xml haarcascade_fullbody.xml haarcascade_lefteye_2splits.xml haarcascade_licence_plate_rus_16stages.xml haarcascade_lowerbody.xml haarcascade_profileface.xml haarcascade_righteye_2splits.xml haarcascade_russian_plate_number.xml haarcascade_smile.xml haarcascade_upperbody.xml
1、人脸检测 cv.CascadeClassifier
1 2 # 人脸检测haarcascade_frontalface_default faceCascade = cv2.CascadeClassifier("XML/haarcascade_frontalface_default.xml")
Dlib 人脸提取+关键点检测
CNN人脸检测模型名称: mmod_human_face_detector.dat.bz2
68维人脸检测模型名称: shape_predictor_68_face_landmarks.dat.bz2
5维人脸检测模型名称 shape_predictor_5_face_landmarks.dat.bz2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 detector = dlib.cnn_face_detection_model_v1(face_detector_model_path) predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat' ) detections = detector(img, 1 ) detection = detections[0 ] shape = predictor(img, detection.rect) landmark_points = shape.parts()