Python 如何使用OpenCV houghlines计算屏幕截图中的选项卡数?
我正在尝试使用OpenCV计算屏幕截图中的选项卡数。我首先裁剪了我的图像,限制在chrome标签上。然后我使用边缘检测,Canny算法在chrome中找到边缘。然后,我使用Houghlines查找选项卡的数量,但我没有通过Houghlines获得所需的输出。下面是我的代码和输出Python 如何使用OpenCV houghlines计算屏幕截图中的选项卡数?,python,opencv,image-processing,edge-detection,hough-transform,Python,Opencv,Image Processing,Edge Detection,Hough Transform,我正在尝试使用OpenCV计算屏幕截图中的选项卡数。我首先裁剪了我的图像,限制在chrome标签上。然后我使用边缘检测,Canny算法在chrome中找到边缘。然后,我使用Houghlines查找选项卡的数量,但我没有通过Houghlines获得所需的输出。下面是我的代码和输出 import cv2 import numpy as np import math from matplotlib import pyplot as plt img = cv2.imread('1.png') gray
import cv2
import numpy as np
import math
from matplotlib import pyplot as plt
img = cv2.imread('1.png')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray,50,200,apertureSize = 3)
cv2.imwrite('result.png',edges)
lines = cv2.HoughLines(edges,1,np.pi/180,50)
for rho,theta in lines[0]:
slope = 180*theta*1.0/np.pi
if slope > 110 and slope <148: # for identifying chrome tab angle (right slope line of each tab)
a = np.cos(theta)
b = np.sin(theta)
x0 = a*rho
y0 = b*rho
x1 = int(x0 + 1000*(-b))
y1 = int(y0 + 1000*(a))
x2 = int(x0 - 1000*(-b))
y2 = int(y0 - 1000*(a))
cv2.line(img,(x1,y1),(x2,y2),(0,0,255),3)
cv2.imwrite('result2.png',img)
导入cv2
将numpy作为np导入
输入数学
从matplotlib导入pyplot作为plt
img=cv2.imread('1.png')
灰色=cv2.CVT颜色(img,cv2.COLOR\U BGR2GRAY)
边缘=cv2.坎尼(灰色,50200,孔径大小=3)
cv2.imwrite('result.png',edges)
线=cv2.霍夫线(边,1,np.pi/180,50)
对于ρ,θ在[0]行中:
斜率=180*θ*1.0/np.pi
如果斜率>110且斜率非常有趣:D
一个非常简单的解决方案是对图像进行二值化,并在图像的上部区域定义一条线,然后获取灰度值。然后你可以数一数十字路口。以下是一个例子:
花哨的算法并不总是最好的解决方案。定义您想要做的事情,并尝试找到尽可能简单的解决方案
这是我在C++中的解决方案。又快又脏;)
#包括“opencv2/imgproc.hpp”
#包括“opencv2/highgui.hpp”
#包括
#包括
#包括
使用名称空间cv;
使用名称空间std;
Mat src、二进制、变形、灰色、变形rgb;
/**
*计算选项卡的数量
*/
int getNumberOfTabs(Mat&src、int start\u col、int stop\u col、int search\u row、bool draw=false);
/**
*@主功能
*/
int main(int argc,字符**argv)
{
常量int morp_size=2;
常数int start_col=5;
常数int stop_col=1750;
const int row_index=2;
///加载图像
src=imread(“C:\\Users\\phili\\Pictures\\Tab.png”,1);
//转换为二值化
CVT颜色(src、灰色、CV_rgb2灰色);
阈值(灰色,二进制,164255,1);
//删除选项卡上的图标和文本
Mat元素=getStructuringElement(CV_形状、大小(2*变形大小+1、2*变形大小+1)、点(变形大小、变形大小));
形态学(二进制、形态、CV_MOP_OPEN、元素);
int nmb_tabs=getNumberOfTabs(变形、开始列、停止列、行索引、真);
imshow(“原件”,src);
imshow(“二进制”,二进制);
imshow(“二进制”,变形);
///等待用户完成程序
while(true)
{
INTC;
c=等待键(20);
如果((字符)c==27)
{
打破
}
}
}
int getNumberOfTabs(Mat&src、int start\u col、int stop\u col、int row\u index、bool draw)
{
整数长度=停止列-开始列;
//提取灰度值轮廓
Mat profil=cv::Mat(0,长度,cv_8U);
profile=src.colRange(开始列、停止列).row(行索引);
Mat src_rgb;
如果(抽签)
{
CVT颜色(src、src_rgb、CV_GRAY2RGB);
行(src_rgb,点(起始列,行索引),点(停止列,行索引),标量(0,0,255),2);
}
//将profil与[1-1]卷积以检测边缘
无符号字符*输入=(无符号字符*)(profil.data);
向量位置;
对于(int i=0;i0),则为else
{
位置。推回(i);
如果(抽签)
圆(src_rgb,点(i+start_col+1,行索引),2,标量(255,0,0),-1);
}
}
如果(抽签)
imshow(“检测到的边缘”,src_rgb);
//选项卡数
返回位置。大小()/2;
}
搜索行为红色,检测到的边缘为蓝色的结果:
非常有趣:D
一个非常简单的解决方案是对图像进行二值化,并在图像的上部区域定义一条线,然后获取灰度值。然后你可以数一数十字路口。以下是一个例子:
花哨的算法并不总是最好的解决方案。定义您想要做的事情,并尝试找到尽可能简单的解决方案
这是我在C++中的解决方案。又快又脏;)
#包括“opencv2/imgproc.hpp”
#包括“opencv2/highgui.hpp”
#包括
#包括
#包括
使用名称空间cv;
使用名称空间std;
Mat src、二进制、变形、灰色、变形rgb;
/**
*计算选项卡的数量
*/
int getNumberOfTabs(Mat&src、int start\u col、int stop\u col、int search\u row、bool draw=false);
/**
*@主功能
*/
int main(int argc,字符**argv)
{
常量int morp_size=2;
常数int start_col=5;
常数int stop_col=1750;
const int row_index=2;
///加载图像
src=imread(“C:\\Users\\phili\\Pictures\\Tab.png”,1);
//转换为二值化
CVT颜色(src、灰色、CV_rgb2灰色);
阈值(灰色,二进制,164255,1);
//删除选项卡上的图标和文本
Mat元素=getStructuringElement(CV_形状、大小(2*变形大小+1、2*变形大小+1)、点(变形大小、变形大小));
形态学(二进制、形态、CV_MOP_OPEN、元素);
int nmb_tabs=getNumberOfTabs(变形、开始列、停止列、行索引、真);
imshow(“原件”,src);
imshow(“二进制”,二进制);
imshow(“二进制”,变形);
///等待用户完成程序
while(true)
{
INTC;
c=等待键(20);
如果((字符)c==27)
{
打破
}
}
}
int getNumberOfTabs(Mat&src、int start\u col、int stop\u col、int row\u index、bool draw)
{
整数长度=停止列-开始列;
//提取灰度值轮廓
Mat profil=cv::Mat(0,长度,cv_8U);
profile=src.colRange(开始列、停止列).row(行索引);
Mat src_rgb;
如果(抽签)
{
CVT颜色(src、src_rgb、CV_GRAY2RGB);
行(src_rgb,点(起始列,行索引),点(停止列,行索引),标量(0,0,255),2);
}
//将profil与[1-1]卷积以检测边缘
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include <vector>
#include <stdlib.h>
#include <stdio.h>
using namespace cv;
using namespace std;
Mat src, binary, morph, gray, morph_rgb;
/**
*Compute number of tabs
*/
int getNumberOfTabs(Mat& src, int start_col, int stop_col, int search_row, bool draw=false);
/**
* @function main
*/
int main(int argc, char** argv)
{
const int morph_size = 2;
const int start_col = 5;
const int stop_col = 1750;
const int row_index = 2;
/// Load an image
src = imread("C:\\Users\\phili\\Pictures\\Tab.png", 1);
//Convert for binarization
cvtColor(src, gray, CV_RGB2GRAY);
threshold(gray, binary, 164, 255, 1);
//Remove icons and text on tabs
Mat element = getStructuringElement(CV_SHAPE_RECT, Size(2 * morph_size + 1, 2 * morph_size + 1), Point(morph_size, morph_size));
morphologyEx(binary, morph, CV_MOP_OPEN, element);
int nmb_tabs = getNumberOfTabs(morph, start_col, stop_col, row_index, true);
imshow("Original", src);
imshow("Binary", binary);
imshow("Binary", morph);
/// Wait until user finishes program
while (true)
{
int c;
c = waitKey(20);
if ((char)c == 27)
{
break;
}
}
}
int getNumberOfTabs(Mat& src,int start_col,int stop_col, int row_index, bool draw)
{
int length = stop_col - start_col;
//Extract gray value profil
Mat profil = cv::Mat(0, length, CV_8U);
profil = src.colRange(start_col, stop_col).row(row_index);
Mat src_rgb;
if (draw)
{
cvtColor(src, src_rgb, CV_GRAY2RGB);
line(src_rgb, Point(start_col, row_index), Point(stop_col, row_index), Scalar(0, 0, 255), 2);
}
//Convolve profil with [1 -1] to detect edges
unsigned char* input = (unsigned char*)(profil.data);
vector<int> positions;
for (int i = 0; i < stop_col - start_col - 1; i++)
{
//Kernel
int first = input[i];
int second = input[i + 1];
int ans = first - second;
//Positiv or negativ slope ?
if (ans < 0)
{
positions.push_back(i + 1);
if(draw)
circle(src_rgb, Point(i + start_col, row_index), 2, Scalar(255,0, 0), -1);
}
else if (ans > 0)
{
positions.push_back(i);
if (draw)
circle(src_rgb, Point(i + start_col + 1, row_index), 2, Scalar(255,0, 0), -1);
}
}
if (draw)
imshow("Detected Edges", src_rgb);
//Number of tabs
return positions.size() / 2;
}