2016-05-31 3 views
3

Я пытаюсь считать объект из изображения. Я использую фотографии журналов, и я использую несколько шагов для получения двоичного изображения. enter image description hereКак считать белый объект на двоичном изображении?

Это мой код:

#include <opencv2/core/core.hpp> 
#include <opencv2/imgproc/imgproc.hpp> 
#include <opencv2/highgui/highgui.hpp> 
#include <iostream> 
#include <features2d.hpp> 
using namespace cv; 
using namespace std; 
int main(int argc, char *argv[]) 
{ 
    //load image 
    Mat img = imread("kayu.jpg", CV_LOAD_IMAGE_COLOR); 
    if(img.empty()) 
     return -1; 
    //namedWindow("kayu", CV_WINDOW_AUTOSIZE); 
    imshow("kayu", img); 

    //convert to b/w 
    Mat bw; 
    cvtColor(img, bw, CV_BGR2GRAY); 
    imshow("bw1", bw); 

    threshold(bw, bw, 40, 255, CV_THRESH_BINARY); 
    imshow("bw", bw); 

    //distance transform & normalisasi 
    Mat dist; 
    distanceTransform(bw, dist, CV_DIST_L2, 3); 
    normalize(dist, dist, 0, 2., NORM_MINMAX); 
    imshow("dist", dist); 

    //threshold to draw line 
    threshold(dist, dist, .5, 1., CV_THRESH_BINARY); 
    imshow("dist2", dist); 

    //dist = bw; 
    //dilasi 
    Mat dilation, erotion, element; 
    int dilation_type = MORPH_ELLIPSE; 
    int dilation_size = 17; 

    element = getStructuringElement(dilation_type, Size(2*dilation_size + 1, 2*dilation_size+1), Point(dilation_size, dilation_size)); 
    erode(dist, erotion, element); 
    int erotionCount = 0; 
    for(int i=0; i<erotionCount; i++){ 
     erode(erotion, erotion, element); 
    } 
    imshow("erotion", erotion); 

    dilate(erotion, dilation, element); 
    imshow("dilation", dilation); 
    waitKey(0); 
    return 0; 
} 

Как вы можете видеть, я использую Эрозия и дилатация, чтобы получить более округлый объект лога. Моя проблема в том, что я застрял в подсчете объекта. Я пробовал SimpleBlobDetector, но ничего не получил, потому что, когда я пытаюсь преобразовать результат этапа «dilation» в CV_8U, белый объект исчезает. У меня тоже была ошибка, когда я использовал findContours(). Он говорит что-то о канале изображения. Я не могу показать ошибку здесь, потому что это слишком много, и я уже удаляю ее из своего кода.

Btw, в конце, я получил 1 канал изображения. enter image description here Могу я просто использовать его для подсчета, или мне нужно его преобразовать и что это лучший способ сделать это?

ответ

3

Два простых шага:

  1. Ищите счетчики для binariezed изображения.
  2. Получить счетчик счетчиков.

Код:

int count_trees(const cv::Mat& bin_image){ 
    cv::Mat img; 
    if(bin_image.channels()>1){ 
     cv::cvtColor(bin_image,img,cv::COLOR_BGR2GRAY); 
    } 
    else{ 
     img=bin_image.clone();; 
    } 
    if(img.type()!=CV_8UC1){ 
     img*=255.f; //This could be stupied, but I do not have an environment to try it 
     img.convertTo(img,CV_8UC1); 
    } 

    std::vector<std::vector<cv::Point>> contours 
    std::vector<Vec4i> hierarchy; 
    cv::findContours(bin_image, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE); 
    return contours.size(); 
} 
+0

Спасибо за ваш ответ. Я пробовал ваш код, но у меня все еще появилась ошибка о неподдерживаемом формате. Сообщение об ошибке вроде этого «Неподдерживаемый формат или комбинация форматов findContours() поддерживает только CV_8u». –

+0

cvtColor (img, bw, CV_BGR2GRAY); порог (bw, bw, 40, 255, CV_THRESH_BINARY); Эти линии гарантируют, что ваше изображение CV_8UC1, поскольку оно было загружено как обычный цвет. Существует другой код, который вызывает эту проблему. вы должны показать нам, что мы знаем –

+0

Я показал весь свой код на вопрос. Я действительно хочу знать, почему это тоже происходит. Я создаю новую функцию из вашего кода, а входной параметр - это расширение. –

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