Python 2.7 用opencv检测停车场
如果是单行(较小的图像),该程序将识别对象 来自未来进口部的Python 2.7 用opencv检测停车场,python-2.7,opencv,opencv3.0,Python 2.7,Opencv,Opencv3.0,如果是单行(较小的图像),该程序将识别对象 来自未来进口部的 从集合导入defaultdict 从集合导入订单 从cv2进口行 进口cv2 从matplotlib导入pyplot作为plt 从networkx.com导入交换 来自numpy进口垫 从撇取风险敞口进口风险敞口 将numpy作为np导入 从组织导入imutils 从numpy.core.defchararray导入rindex 导入系统 def管路(p1、p2): A=(p1[1]-p2[1]) B=(p2[0]-p1[0]) C=
从集合导入defaultdict
从集合导入订单
从cv2进口行
进口cv2
从matplotlib导入pyplot作为plt
从networkx.com导入交换
来自numpy进口垫
从撇取风险敞口进口风险敞口
将numpy作为np导入
从组织导入imutils
从numpy.core.defchararray导入rindex
导入系统
def管路(p1、p2):
A=(p1[1]-p2[1])
B=(p2[0]-p1[0])
C=(p1[0]*p2[1]-p2[0]*p1[1])
返回A,B,-C
def交叉口(L1、L2):
D=L1[0]*L2[1]-L1[1]*L2[0]
Dx=L1[2]*L2[1]-L1[1]*L2[2]
Dy=L1[0]*L2[2]-L1[2]*L2[0]
如果D!=0:
x=Dx/D
y=Dy/D
返回x,y
其他:
返回错误
def通信接口(hline、vline):
hx1=hline[0];hy1=hline[1];hx2=hline[2];hy2=hline[3];
vx3=vline[0];vy3=vline[1];vx4=vline[2];vy4=vline[3];
返回0;
输入=系统argv[1]
#级联分类器类以检测对象。cas1.xml将具有经过培训的数据
face_cascade=cv2.cascade分类器(sys.argv[2])
#im将以图像格式输入
im=cv2.imread(输入)
im2=im
#cvtColor将图像从一个颜色空间转换为另一个颜色空间。
灰色=cv2.CVT颜色(im、cv2.COLOR\U BGR2GRAY)
#使用高斯模糊对平滑图像应用各种线性滤波器
模糊=cv2.高斯模糊(灰色,(5,15),0)
#应用分段
#应用示例:分离出与要分析的对象对应的图像区域。该分离基于对象像素和背景像素之间的强度变化。
#为了区分我们感兴趣的像素和其他像素(最终会被拒绝),我们对每个像素的强度值与阈值(根据要解决的问题确定)进行比较。
#一旦我们正确地分离了重要的像素,我们就可以使用确定的值对它们进行设置以识别它们(即,我们可以为它们指定一个值0(黑色)、255(白色)或任何适合您需要的值)。
ret3,th3=cv2.阈值(模糊,0255,cv2.阈值二元+cv2.阈值大津)
#轮廓可以简单地解释为连接所有连续点(沿边界)的曲线,具有相同的颜色或强度。轮廓线是形状分析、目标检测和识别的有用工具。
#
#为了获得更好的准确度,请使用二进制图像。因此,在找到轮廓之前,应用阈值或canny边缘检测。
#findContours函数修改源图像。所以,若你们想在找到轮廓后得到源图像,那个么就把它存储到其他变量中。
#在OpenCV中,查找轮廓就像从黑色背景中查找白色对象。所以请记住,要找到的对象应该是白色的,背景应该是黑色的。
轮廓,层次=cv2.findContours(th3,cv2.RETR_树,cv2.CHAIN_近似简单)
#到这里,骨架已经画出来了
#要在图像中绘制轮廓,请启用下面的线
#img=cv2.绘制等高线(im,等高线,-1,(0255,0),1)
idx=0
对于轮廓中的cnt:
x、 y,w,h=cv2.boundingRect(cnt)
如果w-x>900且h-y>100:
roi=im[y:y+h,x:x+w]
裁剪直线=im[y:y+h,x:x+w]
#cv2.imshow('crop\u rect',crop\u rect)
#cv2.等待键(0)
idx+=1
cv2.imwrite('crp_contour'+str(idx)+'.jpg',crop_rect)
im4=裁剪直线
im3=裁剪方向
灰色=cv2.CVT颜色(裁剪、cv2.COLOR\U BGR2GRAY)
模糊=cv2.高斯模糊(灰色,(5,15),0)
ret3,th3=cv2.阈值(模糊,0255,cv2.阈值二元+cv2.阈值大津)
轮廓,层次=cv2.查找轮廓(th3,cv2.外部翻新,cv2.链近似简单)
rect=None
对于轮廓中的cnt:
x1=[]
y1=[]
rect=cv2.minareact(cnt)
box=cv2.cv.BoxPoints(矩形)
box=np.int0(box)
x1.追加(框[0][0]);
x1.追加(方框[1][0]);
x1.追加(方框[2][0]);
x1.追加(方框[3][0]);
y1.追加(框[0][1]);
y1.追加(方框[1][1]);
y1.追加(方框[2][1]);
y1.追加(方框[3][1]);
x=np.amin(x1)
y=np.amin(y1)
w=np.amax(x1)
h=np.amax(y1)
#re=cv2.矩形([box])
#x,y,w,h=cv2.boundingRect(cnt)
如果w-x>900且h-y>100:
rect=cv2.minareact(cnt)
box=cv2.cv.BoxPoints(矩形)
box=np.int0(box)
x、 y,w,h=cv2.boundingRect(cnt)
#裁剪1=裁剪[y:y+h,x:x+w]
#cv2.imshow('crop_rect',crop_rect1)
#cv2.等待键(0)
打破
#(左上角(x,y)、(宽度、高度)、旋转角度)
x=rect[0][0]
y=rect[0][1]
w=rect[1][0]
h=rect[1][1]
角度=矩形[2]
如果RCt(2)NP.PI/180×80和θπ/180×170或θ< P>可以通过两个解找到第二个图像的矩形,用C++解决了这个问题,但是你应该能够轻松地将它转换为Python
解决方案1:阈值和计数
1:对图像应用大津阈值
2:放大图像
3:查找等高线
4:查找有效矩形
/**
* Work if no critical lines are completely hide
*/
void identify_ob_by_lines(cv::Mat const &img)
{
cv::Mat gray;
cv::cvtColor(img, gray, CV_BGR2GRAY);
cv::threshold(gray, gray, 0, 255,
cv::THRESH_BINARY | cv::THRESH_OTSU);
cv::Mat edges;
cv::Canny(gray, edges, 30, 90);
std::vector<cv::Vec4i> lines;
cv::HoughLinesP(edges, lines, 1,
CV_PI/180, 50, 50, 10);
std::vector<cv::Vec4i> hor_lines;
std::vector<cv::Vec4i> vec_lines;
//remove lines with invalid angle
for(auto const &l : lines)
{
auto const p1 = cv::Point(l[0], l[1]);
auto const p2 = cv::Point(l[2], l[3]);
auto const angle = abs_line_angle(p1, p2);
if(angle >= 76){
vec_lines.emplace_back(l);
}else if(angle <= 5){
hor_lines.emplace_back(l);
}
}
//remove_adjacent_lines(hor_lines, 1, 400);
remove_adjacent_lines(vec_lines, 0, 30);
//draw lines on blank image
cv::Mat blank = cv::Mat::zeros(img.size(), CV_8U);
draw_lines(blank, hor_lines, {255});
draw_lines(blank, vec_lines, {255});
//find the contours of blank image
std::vector<std::vector<cv::Point>> contours;
cv::findContours(blank.clone(), contours, cv::RETR_TREE,
cv::CHAIN_APPROX_SIMPLE);
for(auto const &contour : contours){
auto const rect = cv::boundingRect(contour);
if(rect.area() >= 2000 &&
(rect.height / static_cast<double>(rect.width)) > 1.0){
//cv::rectangle(img_copy, rect, {255, 0, 0}, 3);
auto const min_rect = cv::minAreaRect(contour);
cv::Point2f rect_points[4];
min_rect.points(rect_points);
for(size_t j = 0; j < 4; ++j){
cv::line(img, rect_points[j],
rect_points[(j+1)%4], {255, 0, 0}, 2, 8);
}
}
}
cv::imshow("img copy", img);
cv::waitKey();
cv::imwrite("result.jpg", blank);
}
代码是
void identify_ob_by_edges(cv::Mat const &img)
{
cv::Mat gray;
cv::cvtColor(img, gray, CV_BGR2GRAY);
cv::threshold(gray, gray, 0, 255,
cv::THRESH_BINARY | cv::THRESH_OTSU);
auto const kernel =
cv::getStructuringElement(cv::MORPH_RECT, {7,7});
cv::dilate(gray, gray, kernel);
std::vector<std::vector<cv::Point>> contours;
cv::findContours(gray.clone(), contours, cv::RETR_TREE,
cv::CHAIN_APPROX_SIMPLE);
cv::Mat img_copy = img.clone();
for(auto const &contour : contours){
auto const rect = cv::boundingRect(contour);
if(rect.area() >= 2000 &&
(rect.height / static_cast<double>(rect.width)) > 1.0){
cv::rectangle(img_copy, rect, {255, 0, 0}, 3);
}
}
cv::imshow("binarize", gray);
cv::imshow("color", img_copy);
cv::waitKey();
cv::imwrite("result.jpg", img_copy);
}
void通过边识别对象(cv::Mat const&img)
{
cv::席灰色;
cv::CVT颜色(img、灰色、cv_bgr2灰色);
cv::阈值(灰色、灰色、0、255、,
cv::THRESH_BINARY(cv::THRESH_OTSU);
自动常量内核=
cv::getStructuringElement(cv::MORPH_RECT,{7,7});
cv::膨胀(灰色、灰色、果仁);
矢量轮廓;
cv::findContours(gray.clone()、等高线、cv::RETR_树、,
cv::链(近似简单);
cv::Mat img_copy=img.clone();
用于(自动常量和等高线:等高线){
自动常量rect=cv::boundingRect(轮廓);
如果(矩形面积()>=2000&&
(垂直高度/静态投影(垂直宽度))>1.0){
矩形(img_copy,rect,{255,0,0},3);
}
}
cv::imshow(“二值化”,灰色);
cv::imshow(“彩色”,img_副本);
cv::waitKey();
简历::imwrite(“result.jpg”,img_copy);
}
结果是
但如果不是所有的线都能被看到,这就不起作用了,这是解决方案二的时候了
2:
/**
* Work if no critical lines are completely hide
*/
void identify_ob_by_lines(cv::Mat const &img)
{
cv::Mat gray;
cv::cvtColor(img, gray, CV_BGR2GRAY);
cv::threshold(gray, gray, 0, 255,
cv::THRESH_BINARY | cv::THRESH_OTSU);
cv::Mat edges;
cv::Canny(gray, edges, 30, 90);
std::vector<cv::Vec4i> lines;
cv::HoughLinesP(edges, lines, 1,
CV_PI/180, 50, 50, 10);
std::vector<cv::Vec4i> hor_lines;
std::vector<cv::Vec4i> vec_lines;
//remove lines with invalid angle
for(auto const &l : lines)
{
auto const p1 = cv::Point(l[0], l[1]);
auto const p2 = cv::Point(l[2], l[3]);
auto const angle = abs_line_angle(p1, p2);
if(angle >= 76){
vec_lines.emplace_back(l);
}else if(angle <= 5){
hor_lines.emplace_back(l);
}
}
//remove_adjacent_lines(hor_lines, 1, 400);
remove_adjacent_lines(vec_lines, 0, 30);
//draw lines on blank image
cv::Mat blank = cv::Mat::zeros(img.size(), CV_8U);
draw_lines(blank, hor_lines, {255});
draw_lines(blank, vec_lines, {255});
//find the contours of blank image
std::vector<std::vector<cv::Point>> contours;
cv::findContours(blank.clone(), contours, cv::RETR_TREE,
cv::CHAIN_APPROX_SIMPLE);
for(auto const &contour : contours){
auto const rect = cv::boundingRect(contour);
if(rect.area() >= 2000 &&
(rect.height / static_cast<double>(rect.width)) > 1.0){
//cv::rectangle(img_copy, rect, {255, 0, 0}, 3);
auto const min_rect = cv::minAreaRect(contour);
cv::Point2f rect_points[4];
min_rect.points(rect_points);
for(size_t j = 0; j < 4; ++j){
cv::line(img, rect_points[j],
rect_points[(j+1)%4], {255, 0, 0}, 2, 8);
}
}
}
cv::imshow("img copy", img);
cv::waitKey();
cv::imwrite("result.jpg", blank);
}