Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

best way to segment a tree in plantation aerial image using opencv

so i want to segment a tree from an aerial image

sample image (original image) :

originalimage

and i expect the result like this (or better) :

result after using photoshop b&w filter first

the first thing i do is using threshold function in opencv and i didn't get expected result (it cant segment the tree crown), and then i'm using black and white filter in photoshop using some adjusted parameter (the result is shown beloww) and do the threshold and morphological filter and got result like shown above.

photoshop b&w

my question, is there a some ways to do the segmentation to the image without using photoshop first, and produce segmented image like the second image (or better) ? or maybe is there a way to do produce image like the third image ?

ps: you can read the photoshop b&w filter question here : https://dsp.stackexchange.com/questions/688/whats-the-algorithm-behind-photoshops-black-and-white-adjustment-layer

like image 533
jajamaharaja Avatar asked Jul 09 '15 07:07

jajamaharaja


1 Answers

You can do it in OpenCV. The code below will basically do the same operations you did in Photoshop. You may need to tune some of the parameters to get exactly what you want.

#include "opencv2\opencv.hpp"
using namespace cv;

int main(int, char**)
{
    Mat3b img = imread("path_to_image");

    // Use HSV color to threshold the image
    Mat3b hsv;
    cvtColor(img, hsv, COLOR_BGR2HSV);

    // Apply a treshold
    // HSV values in OpenCV are not in [0,100], but:
    // H in [0,180]
    // S,V in [0,255]

    Mat1b res;
    inRange(hsv, Scalar(100, 80, 100), Scalar(120, 255, 255), res);

    // Negate the image
    res = ~res;

    // Apply morphology 
    Mat element = getStructuringElement( MORPH_ELLIPSE, Size(5,5));
    morphologyEx(res, res, MORPH_ERODE, element, Point(-1,-1), 2);
    morphologyEx(res, res, MORPH_OPEN, element);

    // Blending
    Mat3b green(res.size(), Vec3b(0,0,0));
    for(int r=0; r<res.rows; ++r) {
        for(int c=0; c<res.cols; ++c) {
            if(res(r,c)) { green(r,c)[1] = uchar(255); }
        }
    }

    Mat3b blend;
    addWeighted(img, 0.7, green, 0.3, 0.0, blend);

    imshow("result", res);
    imshow("blend", blend);
    waitKey();

    return 0;
}

The resulting image is:

enter image description here

The blended image is:

enter image description here

like image 112
Miki Avatar answered Sep 29 '22 02:09

Miki