Идея действительно проста. Используйте morphology , чтобы выделить текст, который вы хотите обнаружить. Используя это изображение, создайте маску , чтобы удалить интересующую область на входном изображении и получить окончательное изображение. Все через морфологию. Мой ответ на C ++, но реализация очень проста:
//Read input image:
std::string imagePath = "C://opencvImages//commentImage.png";
cv::Mat imageInput= cv::imread( imagePath );
//Convert it to grayscale:
cv::Mat grayImg;
cv::cvtColor( imageInput, grayImg, cv::COLOR_BGR2GRAY );
//Get binary image via Otsu:
cv::threshold( grayImg, grayImg, 0, 255 , cv::THRESH_OTSU );
До этого момента вы генерировали двоичное изображение. Теперь давайте dilate
изображение, используя rect angular структурирующий элемент (SE
) шире, чем выше. Идея состоит в том, что я хочу соединить весь текст по горизонтали И по вертикали (чуть-чуть). Если вы видите входное изображение, текст «TEST132212» немного отделен от комментария, кажется, этого достаточно, чтобы пережить операцию dilate
. Давайте посмотрим, здесь я использую SE
размера 9 x 6
с 2
итерациями:
cv::Mat morphKernel = cv::getStructuringElement( cv::MORPH_RECT, cv::Size(9, 6) );
int morphIterations = 2;
cv::morphologyEx( grayImg, grayImg, cv::MORPH_DILATE, morphKernel, cv::Point(-1,-1), morphIterations );
Это результат:
Я получил уникальный блок, где был оригинальный комментарий - Отлично! Теперь это самый большой шарик на изображении. Если я вычту его в исходное двоичное изображение, я должен сгенерировать маску , которая успешно изолирует все, что не является «комментарием»:
cv::Mat bigBlob = findBiggestBlob( grayImg );
Я получаю это:
![enter image description here](https://i.stack.imgur.com/IiSfA.png)
Теперь двоичная маска поколение:
cv::Mat binaryMask = grayImg - bigBlob;
//Use the binaryMask to produce the final image:
cv::Mat resultImg;
imageInput.copyTo( resultImg, binaryMask );
Создает замаскированное изображение:
![enter image description here](https://i.stack.imgur.com/HY9tn.png)
Теперь вы должны были отметить функцию findBiggestBlob
. Это функция, которую я сделал, которая возвращает самый большой двоичный объект в двоичном изображении. Идея состоит в том, чтобы просто рассчитать все контуры входного изображения, вычислить их площадь и сохранить контур с наибольшей площадью сгустка. Это реализация C ++:
//Function to get the largest blob in a binary image:
cv::Mat findBiggestBlob( cv::Mat &inputImage ){
cv::Mat biggestBlob = inputImage.clone();
int largest_area = 0;
int largest_contour_index=0;
std::vector< std::vector<cv::Point> > contours; // Vector for storing contour
std::vector<cv::Vec4i> hierarchy;
// Find the contours in the image
cv::findContours( biggestBlob, contours, hierarchy,CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );
for( int i = 0; i< (int)contours.size(); i++ ) {
//Find the area of the contour
double a = cv::contourArea( contours[i],false);
//Store the index of largest contour:
if( a > largest_area ){
largest_area = a;
largest_contour_index = i;
}
}
//Once you get the biggest blob, paint it black:
cv::Mat tempMat = biggestBlob.clone();
cv::drawContours( tempMat, contours, largest_contour_index, cv::Scalar(0),
CV_FILLED, 8, hierarchy );
//Erase the smaller blobs:
biggestBlob = biggestBlob - tempMat;
tempMat.release();
return biggestBlob;
}