1

OpenCV를 사용하여 스크린 샷의 탭 수를 계산하려고합니다. 크롬 탭으로 제한하기 위해 먼저 이미지를 자릅니다. 그런 다음 가장자리 감지, Canny 알고리즘을 사용하여 크롬에서 가장자리를 찾습니다. 그런 다음 Houghlines를 사용하여 탭 수를 찾았으나 Houghlines를 통해 필요한 출력을 얻지 못하고 있습니다. 아래는 내 코드와 출력입니다.OpenCV 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

답변

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

+0

이봐. 나는이 주제에 익숙하지 않다. 이미지를 바이너리 화하기 위해 무엇을했는지 말해 줄 수 있습니까? 나는 일련의 이미지를 가지고있다. 모든 이미지의 탭 수의 평균을 찾고 싶습니다. –

+1

[ImageJ] (https://imagej.nih.gov/ij/)를 사용했습니다. 오픈 소스 이미지 처리 도구입니다. 새 프로젝트를 만들 필요없이 몇 가지 아이디어를 테스트 할 수 있습니다. ...! [여기] (https://imagingbook.com/source/)에서 유용한 플러그인을 다운로드 할 수 있습니다. 그러나 기본적으로 나는 이미지를 8 비트로 변환하고, 전역 임계 값 (8 비트 이미지 히스토그램 참조)을 사용하고 이진화를 수행했다. OpenCV에서는'CV_LOAD_IMAGE_GRAYSCALE' 플래그로 이미지를로드하거나'cv2.cvtColor'로 컬러 이미지를 변환하고'cv2.threshold'로 thresholding을 할 수 있습니다. – PSchn

+0

고맙습니다. 이미지를 이진화 할 수 있습니다. 너 내가 줄을 도우면서 교차점을 계산하려면 어떻게 도와 주실 수 있겠습니까? 나는 python으로 opencv를 사용하고있다 –

관련 문제