2015-06-01 5 views
2

Я сравнительно новичок в OpenCV. Мне было интересно, можно ли получить гистограмму контура (который может быть идеальной прямоугольной или неправильной формой), найденной findcontour.Гистограмма OpenCV неправильной формы

Заранее спасибо.

Edit:

Это то, что именно я пытаюсь добиться. Я хочу проанализировать область в контуре для обнаружения дефектов (путем анализа гистограммы области?) И объявить дефектную или хорошую часть. Изображения прилагаются.

Хороший образец. (Контур обнаружено описана в сером цвете)

enter image description here

Дефектный образец. (Дефект вокруг верхнего левого угла)

enter image description here

+0

ли вы имеете в виду вы хотите гистограмму пикселей, ограниченный контур ? –

+0

@RogerRowland Это именно то, что мне нужно. – dhruvvyas90

+1

Краткое руководство: 1) используйте контуры для создания маски с использованием 'drawContours', 2) подайте свою маску в качестве 4-го параметра в' calcHist'. –

ответ

1

Вы можете, вероятно, неправильно гистограмму.

Contour образа должен быть двоичным-значной, цвет меньше матрица , которая не представляет собой полутоновое уровне пикселей, но границы. Между тем, histogram - это инструмент для анализа того, как распределенные по шкале серого пиксели распределяются в вашем 2D-изображении, не так ли?

Итак, почему вы хотите профилировать матрицу двоичных значений histogram, которая может не помочь вам проанализировать изображение? Однако гистограмма не подходит для анализа контуров.

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

+0

Хотя вы правы в злоупотреблении частью, скажем, я все равно хочу это сделать, т.е. получив две гистограммы. Как мне это сделать ? – dhruvvyas90

+1

Вам нужно нарисовать контурную последовательность на изображении (или матрице), размер которого такой же, как у исходного изображения. Вы получите двоично-значную матрицу, которую вы можете использовать для проецирования. Ссылка: http://docs.opencv.org/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html?highlight=drawcontours#drawcontours –

1

Вот еще один способ, используя морфологические операции.

#include <string> 
#include <iostream> 
#include "opencv2/imgproc/imgproc.hpp" 
#include "opencv2/highgui/highgui.hpp" 

cv::Mat make_element(int morph_size, int elem_type) 
{ 
    cv::Size sz{2*morph_size+1, 2*morph_size+1}; 
    cv::Point pt{morph_size, morph_size}; 
    cv::Mat element{getStructuringElement(elem_type, sz, pt)}; 
    return element; 
} 

int main(int argc, char **argv) 
{ 
    std::string fn{argv[1]}; 
    cv::Mat src{cv::imread(fn)}, dst, mask[3]; 

    if (!src.data) { 
     std::cerr << "No image data :(" << std::endl; 
     return -1; 
    } 

    // Clean out noise 
    cv::Mat elem1{make_element(5, cv::MORPH_RECT)}; 
    cv::morphologyEx(src, dst, cv::MORPH_OPEN, elem1); 

    // Close the hole, then XOR with original 
    cv::Mat elem2{make_element(45, cv::MORPH_ELLIPSE)}; 
    morphologyEx(dst, dst, cv::MORPH_CLOSE, elem2); 
    cv::bitwise_xor(src, dst, dst); 

    // Clean out noise (again) 
    cv::Mat elem3{make_element(1, cv::MORPH_RECT)}; 
    cv::morphologyEx(dst, dst, cv::MORPH_OPEN, elem3); 

    // Mark the hole 
    cv::split(dst, mask); 
    cv::bitwise_xor(src, dst, dst, mask[0]); 

    // Overlay 
    cv::split(dst, mask); 
    cv::Mat empty{dst.size(), CV_8UC1}; 
    std::vector<cv::Mat> v{empty, empty, mask[0]}; 
    cv::merge(v, dst); 
    cv::bitwise_or(src, dst, dst); 

    cv::namedWindow("Defect (ESC to quit)", cv::WINDOW_NORMAL); 
    cv::startWindowThread(); 
    cv::imshow("Defect (ESC to quit)", dst); 
    while (true) { 
     int k = cv::waitKey(100) & 0xff; 
     if (k == 27) { 
      break; 
     } 
    } 
    cv::destroyAllWindows(); 

    return 0; 
}; 

Некоторое дополнительное чтение:

Смежные вопросы