매우 흥미로운 : 정말 간단한 해결책이 이미지를 이진화하고의 상단 영역에 선을 정의하는 것입니다 D 회색 값을 얻으십시오. 다음 교차로를 셀 수 있습니다. 예를 들면 다음과 같습니다.
멋진 알고리즘은 항상 최상의 솔루션입니다. 원하는 것을 정의하고 가능한 한 간단하게 솔루션을 찾으십시오.
여기 내 솔루션은 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;
}
과 빨간색의 검색 라인과 파란색으로 감지 가장자리 결과 :
이봐. 나는이 주제에 익숙하지 않다. 이미지를 바이너리 화하기 위해 무엇을했는지 말해 줄 수 있습니까? 나는 일련의 이미지를 가지고있다. 모든 이미지의 탭 수의 평균을 찾고 싶습니다. –
[ImageJ] (https://imagej.nih.gov/ij/)를 사용했습니다. 오픈 소스 이미지 처리 도구입니다. 새 프로젝트를 만들 필요없이 몇 가지 아이디어를 테스트 할 수 있습니다. ...! [여기] (https://imagingbook.com/source/)에서 유용한 플러그인을 다운로드 할 수 있습니다. 그러나 기본적으로 나는 이미지를 8 비트로 변환하고, 전역 임계 값 (8 비트 이미지 히스토그램 참조)을 사용하고 이진화를 수행했다. OpenCV에서는'CV_LOAD_IMAGE_GRAYSCALE' 플래그로 이미지를로드하거나'cv2.cvtColor'로 컬러 이미지를 변환하고'cv2.threshold'로 thresholding을 할 수 있습니다. – PSchn
고맙습니다. 이미지를 이진화 할 수 있습니다. 너 내가 줄을 도우면서 교차점을 계산하려면 어떻게 도와 주실 수 있겠습니까? 나는 python으로 opencv를 사용하고있다 –