利用Opencv 寻找凸四边形的四个顶点
对于一个含有凸四边形的图像,要想定位出凸四边形的四个顶点的坐标。
首先,得先对图像进行边缘检测,而边缘检测的前提是二值化图像【未进行二值化的图像进行边缘检测得到的结果往往非常不理想】,根据实际图像的特点,我对图像进行二值化处理以及闭运算【主要去除目标物内的孤立点】的过程如下:
import cv2
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']
img=cv2.imread(r"C:\Users\li1223\Desktop\DSC_0059.jpg")
gray_1 = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
h,w=img.shape[0:2]
gray=np.zeros((h,w),dtype=img.dtype)
for i in range(h):
for j in range(w):
gray[i,j]=max(img[i,j,0],img[i,j,1],img[i,j,2])
gray_avarage = np.sum(gray)/(h*w)
pp = np.where(gray>gray_avarage)
gray1 = np.zeros((h,w),dtype=img.dtype)
gray1[pp]=1
kernel = np.ones((5,5), np.uint8)
closing = cv2.morphologyEx(gray1,cv2.MORPH_CLOSE,kernel)
cv2.imshow('二值化图像',closing)
cv2.waitKey(0)
效果图:

原图

二值化图
对得到的二值化图像可知,在凸四边形目标物的外围依旧有不规则孔洞和孤立小点,我们根据实际情况,如果只是有很多孤立的小点可以采用图像形态学开运算进行处理,如果有较大的不规则孔洞,可以采用联通区域的面积进行判别筛选处理。
代码如下:
import cv2
import numpy as np
img = cv2.imread(r'C:\Users\li1223\Desktop\222.png', cv2.IMREAD_COLOR)
h, w, _ = img.shape
GrayImage=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,binary = cv2.threshold(GrayImage,40,255,cv2.THRESH_BINARY)
threshold = h/20 * w/20
"""提取二值化后图片中的轮廓信息 ,返回值contours存储的即是图片中的轮廓信息,是一个向量,内每个元素保存了一组由连续的Point点构成的点的集合的向量,每一组Point点集就是一个轮廓,有多少轮廓,向量contours就有
多少元素"""
contours,hierarch=cv2.findContours(binary,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
for i in range(len(contours)):
area = cv2.contourArea(contours[i])
if area < threshold:
cv2.drawContours(img,[contours[i]],-1, (0,0,0), thickness=-1)
continue
cv2.namedWindow("clahe image", 0)
cv2.resizeWindow("clahe image", 640, 480)
cv2.imshow("clahe image111", img)
cv2.waitKey(0)
cv2.imwrite(r'C:\Users\li1223\Desktop\2222.png',img)

去除目标物外孔洞的二值化图
其次,将凸四边形的轮廓凸显出来(此时的轮廓含有各种毛刺边),所以再利用凸显出来的轮廓寻找凸区域勾画出轮廓的整体(去除了毛刺边)【此时,可以得到勾画轮廓的系列点,顶点也在其中】。对系列点进行椭圆拟合【通常使用最小二乘法】,可以得到椭圆质点、长短轴半径以及旋转角度【根据最小二乘法的原理得,此椭圆是不会将顶点包含在内】。最后,利用拟合所得的椭圆参数构建椭圆方程,将系列点带入计算。包含在椭圆内的点,计算值为负,在椭圆上的点,计算值为零,在椭圆外的点,计算为正。
将计算值为正的点提取出来【顶点就在其中】构建点集,第一步挑选出计算值最大的点作为第一个顶点,然后去除第一个顶点附近的点和它本身,利用剩下的点构建一个新的点集【此时新的点集包含剩余的三个顶点以及这三个顶点附近的点】;第二步在新的点集中,挑选出计算值最大的点作为第二个顶点,然后去除第二个顶点附近的点和它本身,利用剩下的点构建一个新的点集【此时新的点集包含剩余的二个顶点以及这二个顶点附近的点】;依次类推,得到全部四个点。
假设得到椭圆质点【也称中心点】
\tfrac{(x^{'}cos\theta-y^{'}sin\theta)^{2}}{b^{2}}+\tfrac{(x^{'}sin\theta+y^{'}cos\theta)^{2}}{a^{2}}=1
b2(x′cosθ−y′sinθ)2+a2
(x′sinθ+y′cosθ)2=1
化解,得到
(a^{2}cos^{2}\theta+b^{2}sin^{2}\theta)x^{'2}+(a^{2}sin^{2}\theta+b^{2}cos^{2}\theta)y^{'2}+2cos\theta sin\theta(b^{2}-a^{2})x^{'}y^{'}-a^{2}b^{2}=0
(a2cos2θ+b2sin2θ)x′2+(a2sin2θ+b2cos2θ)y′2+2cosθsinθ(b2−a2)x′y′−a2b2=0
则有:
Img = cv2.imread(r'C:\Users\li1223\Desktop\2222.png')
imgray = cv2.cvtColor(Img, cv2.COLOR_BGR2GRAY)
B = imgray.copy()
ret, thresh = cv2.threshold(imgray, 150, 255, 0)
contours, hierarchy = cv2.findContours(thresh,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
hull = cv2.convexHull(contours[len(contours)-1])
cv2.polylines(Img, [hull], True, (0, 255, 0), 2)
elps =
cv2.fitEllipseAMS(hull)
cv2.ellipse(Img, elps, (0,0,255))
center ,a_b ,angle = elps
center_x ,center_y = center
b ,a = a_b
angle = angle/180*np.pi
C = math.pow(a/2*math.sin(angle),2)+math.pow(b/2*math.cos(angle),2)
B = 2*(-math.pow(a/2,2)+math.pow(b/2,2))*math.sin(angle)*math.cos(angle)
A = math.pow(a/2*math.cos(angle),2)+math.pow(b/2*math.sin(angle),2)
f = -math.pow(a/2*b/2,2)
center_array = np.array([center_x,center_y])
point_set = hull.reshape(hull.shape[0],-1)
hh = point_set-center_array
distance = A*np.power(hh[:,0],2)+B*hh[:,0]*hh[:,1]+C*np.power(hh[:,1],2)+f
gg = np.where(distance>0)
dd = hull.reshape(hull.shape[0], -1)[gg[0],:]
dd_1 = np.copy(dd)
radius=8
color=(255,0,0)
thickness=4
first_point = hull.reshape(hull.shape[0], -1)[np.argsort(distance)[-1:]].reshape(2, )
cv2.circle(Img, tuple(first_point), radius, color, thickness)
a_1 = np.sqrt(np.power((first_point-dd)[:,0],2)+np.power((first_point-dd)[:,1],2))
b_1 = np.sqrt(np.power((first_point-center_array)[0],2)+np.power((first_point-center_array)[1],2))
c_1 = np.sqrt(np.power((dd-center_array)[:,0],2)+np.power((dd-center_array)[:,1],2))
cos = (np.power(b_1,2)+np.power(c_1,2)-np.power(a_1,2))/(2*b_1*c_1) - math.cos(20/180*np.pi)
cos_ad = np.where(cos < 0)
dd_1 = dd_1[cos_ad]
dd_2 = np.copy(dd_1)
hh = dd_2-center_array
distance_1 = A*np.power(hh[:,0],2)+B*hh[:,0]*hh[:,1]+C*np.power(hh[:,1],2)+f
scend_point = dd_2[np.argsort(distance_1)[-1:]].reshape(2,
)
cv2.circle(Img, tuple(scend_point), radius, color, thickness)
a_2 = np.sqrt(np.power((scend_point-dd_2)[:,0],2)+np.power((scend_point-dd_2)[:,1],2))
b_2 = np.sqrt(np.power((scend_point-center_array)[0],2)+np.power((scend_point-center_array)[1],2))
c_2 = np.sqrt(np.power((dd_2-center_array)[:,0],2)+np.power((dd_2-center_array)[:,1],2))
cos_2 = (np.power(b_2,2)+np.power(c_2,2)-np.power(a_2,2))/(2*b_2*c_2) - math.cos(20/180*np.pi)
cos_ad = np.where(cos_2 < 0)
dd_2 = dd_2[cos_ad]
dd_3 = np.copy(dd_2)
hh = dd_3-center_array
distance_2 = A*np.power(hh[:,0],2)+B*hh[:,0]*hh[:,1]+C*np.power(hh[:,1],2)+f
third_point = dd_3[np.argsort(distance_2)[-1:]].reshape(2, )
cv2.circle(Img, tuple(third_point), radius, color, thickness)
a_3 = np.sqrt(np.power((third_point-dd_3)[:,0],2)+np.power((third_point-dd_3)[:,1],2))
b_3 = np.sqrt(np.power((third_point-center_array)[0],2)+np.power((third_point-center_array)[1],2))
c_3 = np.sqrt(np.power((dd_3-center_array)[:,0],2)+np.power((dd_3-center_array)[:,1],2))
cos_3 = (np.power(b_3,2)+np.power(c_3,2)-np.power(a_3,2))/(2*b_3*c_3) - math.cos(20/180*np.pi)
cos_ad = np.where(cos_3 < 0)
dd_3 = dd_3[cos_ad]
dd_4 = np.copy(dd_3)
hh = dd_4-center_array
distance_3 = A*np.power(hh[:,0],2)+B*hh[:,0]*hh[:,1]+C*np.power(hh[:,1],2)+f
fourth_point = dd_4[np.argsort(distance_3)[-1:]].reshape(2, )
cv2.circle(Img, tuple(fourth_point), radius, color, thickness)
cv2.circle(Img, tuple([int(center_x),int(center_y)]), radius, color=(0,0,255), thickness=10)
cv2.imwrite(r'C:\Users\li1223\Desktop\22222.png',Img)
cv2.imshow("Perfectly fitted ellipses", Img)
cv2.waitKey(0)
利用Opencv 寻找凸四边形的四个顶点 对于一个含有凸四边形的图像,要想定位出凸四边形的四个顶点的坐标。 首先,得先对图像进行边缘检测,而边缘检测的前提是二值化图像【未进行二值化的图像进行边缘检测得到的结果往往非常不理想】,根据实际图像的特点,我对图像进行二值化处理以及闭运算【主要去除目标物内的孤立点】的过程如下:#图像灰度处理 最大值灰度import cv2import numpy as npimport matplotlib.pyplot as pltplt.rcParams['
python图像处理——关于获得最小外接矩形如何获取该矩形的四个顶点坐标,以及截取进行仿射变换后矩形内的图像(cv2.boxPoints()、cv2.minAreaRect())待完善
前言在获取想要轮廓的点集后,可用cv2.minAreaRect()获取点集的最小外接矩形。返回值rect内包含该矩形的中心点坐标、高度宽度及倾斜角度等信息,使用cv2.boxPoints()可获取该矩形的四个顶点坐标。
但我们并不清楚这四个坐标点各对应着矩形的哪一个顶点,因此无法充分地利用这些坐标信息。可以从坐标值的大小特征入手,将四个坐标与矩形的四个顶点匹配起来:在opencv的坐标体系下,纵坐标最小的是top_point,纵坐标最大的是bottom_point, 横坐标最小的是left_point,横坐
本项目分别提供了以下功能:人脸图像采集,数据训练,人脸识别,删除数据。
图像采集将打开电脑摄像头获取人脸到,数据训练调用了包和xml文件(都在文件夹里),训练速度超快,人脸识别模块可以识别出训练好的人脸。
基于python3,有多个py文件,大部分为带opencv的包,没有界面但可交互,功能齐全,准确率可通过训练数据的加大提升。
如何用检测由直线构成的四边形(多边形)? 这个问题自己困扰了十来天, 查了相关的算法书
(a modern approach, algorithms and applications, computer and machine vision,
Feature Extraction & Image Processing ), 并未找到直接的内容可以使用
这阵子看了一些论文,
OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉库,可以运行在Linux、Windows、Android和Mac OS操作系统上。它轻量级而且高效——由一系列 C 函数和少量 C++ 类构成,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。
OpenCV用C++语言编写,它的主要接口也是C++语言,但是依然保留了大量的C语言接口。该库也有大量的Python、Java and MATLAB/OCTAVE(版本2.5)的接口。这些语言的API接口函数可以通过在线文档获得。如今也提供对于C#、Ch、Ruby,GO的支持。
所有新的开发和算法都是用C++接口。一个使用CUDA的GPU接口也于2010年9月开始实现。
1. 定义每条线段的起点和终点坐标。假设四边形的线段分别为AB、BC、CD、DA。
2. 计算AB和CD的交点P,以及BC和DA的交点Q。可以使用向量叉积来计算两条线段是否相交,如果相交则求出交点。
3. 计算线段AB和线段CD的中点M1,以及线段BC和线段DA的中点M2。
4. 如果点P在M1和M2之间,则P是顶点之一;如果点Q在M1和M2之间,则Q是顶点之一。
5. 重复步骤2到4,可以确定四边形的所有顶点。
qq_42828007: