2016-04-29 9 views
1

Я использую библиотеку обработки изображений Halcon MVTec в течение полугода и OpenCV в течение 1 года.Почему OpenCV не имеет специализированной структуры данных для региона?

1. Одна вещь, которую я обнаружил, что Halcon намного превосходит OpenCV, заключается в том, что OpenCV не имеет специализированной структуры данных для региона.

Это много отходов, если я хочу хранить небольшую область в большом пространстве. Если OpenCV не имеет специализированной структуры данных для региона, отличного от Mat Class.

2. Второй, который является результатом предыдущего, заключается в том, что OpenCV неудобно перебирать области.

Представьте сценарий, что у меня есть 10 подключенных блоков региона после выполнения порога, и я хочу повторить эти 10 блоков для обработки каждого из них. Насколько мне известно, я должен сначала использовать findContours, чтобы получить все контуры каждого региона, а затем я использую drawContour для получения этого региона. Могу ли я сказать, что регионы хранятся по контурным данным, и каждый раз, когда я хочу вернуть регион назад, мне нужно вызвать drawContours?

Mat myImage = imread("Path_To_Source_Image"); 
threshold(myImage, region, 128, 1, THRESH_BINARY); 
vector<vector<Point>> contours; 
findContours(region, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE); 
for (int i = 0; i < contours.size, i++){ 
    Mat oneBlock(myImage.size(), CV_8U); 
    drawContours(oneBlock, contours, i, Scalar(255), -1); 
     // Now I finally get my region 

     // *************************************** 
     // 
     // Do my image procesing for that region 
     // 
     // *************************************** 
    } 
+0

К сожалению, у меня нет опыта Halcon. Можете ли вы лучше объяснить, какие регионы? Являются ли они своего рода суб-изображениями или похожими на разреженные пиксельные местоположения? Какая обработка возможна в регионах? Из моего понимания/интуиции комбинация субимагов и масок может быть регионами. – Micka

+0

"и каждый раз, когда я хочу вернуть регион назад, мне нужно вызвать drawContours?" - Почему бы просто не вспомнить результат drawContours? – Micka

ответ

2

Общий подход для представления областей является использование Mat1i (так называемый Mat типа CV_32S), который содержит индексы регионов, т.е. labels.

Вы можете получить доступ к I-й регион просто с: Mat1b region_mask = (labels == i);

С OpenCV < 3.0, вы можете использовать findConturs и drawContours создать labels изображение:

#include <opencv2\opencv.hpp> 
#include <vector> 
using namespace cv; 
using namespace std; 

int main() 
{ 
    // Read image from file 
    Mat1b img = imread("path_to_image", IMREAD_GRAYSCALE); 

    Mat1b region; 
    threshold(img, region, 200, 255, THRESH_BINARY); 

    vector<vector<Point>> contours; 
    findContours(region.clone(), contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE); 

    Mat1i labels(img.rows, img.cols, int(0)); 
    int n_labels = contours.size(); 

    for (int i = 0; i < contours.size(); ++i) 
    { 
     drawContours(labels, contours, i, Scalar(i + 1), CV_FILLED); // Note the +1, since 0 is the background 
    } 

    // Now you can get your regiones as: 

    // Label "0" is the background 
    for (int i = 1; i <= n_labels; ++i) 
    { 
     Mat1b region_mask = (labels == i); 
     imshow("Region", region_mask); 
     waitKey(); 
    } 

    return 0; 
} 

С OpenCV> = 3.0 вы можете использовать connectedComponents, который будет напрямую возвращать labels:

#include <opencv2\opencv.hpp> 
#include <vector> 
using namespace cv; 
using namespace std; 

int main() 
{ 
    // Read image from file 
    Mat1b img = imread("path_to_image", IMREAD_GRAYSCALE); 

    Mat1b region; 
    threshold(img, region, 200, 255, THRESH_BINARY); 

    Mat1i labels; 
    int n_labels = connectedComponents(region, labels); 

    // Now you can get your regiones as: 

    // Label "0" is the background 
    for (int i = 1; i <= n_labels; ++i) 
    { 
     Mat1b region_mask = (labels == i); 
     imshow("Region", region_mask); 
     waitKey(); 
    } 

    return 0; 
}