如何使用OpenCV houghlines计算屏幕截图中的标签数量?

时间:2016-08-23 11:32:19

标签: python opencv image-processing edge-detection hough-transform

我正在尝试使用OpenCV计算屏幕截图中的标签数量。我首先裁剪我的图像以限制镀铬标签。然后我使用边缘检测,Canny算法来查找chrome中的边缘。然后我使用Houghlines查找选项卡的数量,但我没有通过Houghlines获得所需的输出。下面是我的代码和输出。

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)

Original cropped image Final Image

Firefox image

enter image description here

1 个答案:

答案 0 :(得分:5)

非常有趣:D 一个非常简单的解决方案是将图像二值化并在图像的上部区域定义一条线并获得灰度值。然后你可以计算交叉点。这是一个例子: Finding number of tabs from gray value profile

花哨的算法并不总是最好的解决方案。定义您想要做的事情,并尝试尽可能简单地找到解决方案。

这是我在C ++中的解决方案。又快又脏;)

#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;
}

以及搜索线为红色且检测到的边缘为蓝色的结果: enter image description here