Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>This is my final post using the traditional image processing approaches...</p> <p>Here I somehow combine my two other proposals, <strong>achieving even better results</strong>. As a matter of fact I cannot see how these results could be better (especially when you look at the masked images that the method produces).</p> <p>At the heart of the approach is the combination of <strong>three key assumptions</strong>:</p> <ol> <li>Images should have high fluctuations in the tree regions</li> <li>Images should have higher intensity in the tree regions</li> <li>Background regions should have low intensity and be mostly blue-ish</li> </ol> <p>With these assumptions in mind the method works as follows:</p> <ol> <li>Convert the images to HSV</li> <li>Filter the V channel with a LoG filter</li> <li>Apply hard thresholding on LoG filtered image to get 'activity' mask A</li> <li>Apply hard thresholding to V channel to get intensity mask B</li> <li>Apply H channel thresholding to capture low intensity blue-ish regions into background mask C</li> <li>Combine masks using AND to get the final mask</li> <li>Dilate the mask to enlarge regions and connect dispersed pixels</li> <li>Eliminate small regions and get the final mask which will eventually represent only the tree</li> </ol> <p>Here is the code in MATLAB (again, the script loads all jpg images in the current folder and, again, this is far from being an optimized piece of code):</p> <pre><code>% clear everything clear; pack; close all; close all hidden; drawnow; clc; % initialization ims=dir('./*.jpg'); imgs={}; images={}; blur_images={}; log_image={}; dilated_image={}; int_image={}; back_image={}; bin_image={}; measurements={}; box={}; num=length(ims); thres_div = 3; for i=1:num, % load original image imgs{end+1}=imread(ims(i).name); % convert to HSV colorspace images{end+1}=rgb2hsv(imgs{i}); % apply laplacian filtering and heuristic hard thresholding val_thres = (max(max(images{i}(:,:,3)))/thres_div); log_image{end+1} = imfilter( images{i}(:,:,3),fspecial('log')) &gt; val_thres; % get the most bright regions of the image int_thres = 0.26*max(max( images{i}(:,:,3))); int_image{end+1} = images{i}(:,:,3) &gt; int_thres; % get the most probable background regions of the image back_image{end+1} = images{i}(:,:,1)&gt;(150/360) &amp; images{i}(:,:,1)&lt;(320/360) &amp; images{i}(:,:,3)&lt;0.5; % compute the final binary image by combining % high 'activity' with high intensity bin_image{end+1} = logical( log_image{i}) &amp; logical( int_image{i}) &amp; ~logical( back_image{i}); % apply morphological dilation to connect distonnected components strel_size = round(0.01*max(size(imgs{i}))); % structuring element for morphological dilation dilated_image{end+1} = imdilate( bin_image{i}, strel('disk',strel_size)); % do some measurements to eliminate small objects measurements{i} = regionprops( logical( dilated_image{i}),'Area','BoundingBox'); % iterative enlargement of the structuring element for better connectivity while length(measurements{i})&gt;14 &amp;&amp; strel_size&lt;(min(size(imgs{i}(:,:,1)))/2), strel_size = round( 1.5 * strel_size); dilated_image{i} = imdilate( bin_image{i}, strel('disk',strel_size)); measurements{i} = regionprops( logical( dilated_image{i}),'Area','BoundingBox'); end for m=1:length(measurements{i}) if measurements{i}(m).Area &lt; 0.05*numel( dilated_image{i}) dilated_image{i}( round(measurements{i}(m).BoundingBox(2):measurements{i}(m).BoundingBox(4)+measurements{i}(m).BoundingBox(2)),... round(measurements{i}(m).BoundingBox(1):measurements{i}(m).BoundingBox(3)+measurements{i}(m).BoundingBox(1))) = 0; end end % make sure the dilated image is the same size with the original dilated_image{i} = dilated_image{i}(1:size(imgs{i},1),1:size(imgs{i},2)); % compute the bounding box [y,x] = find( dilated_image{i}); if isempty( y) box{end+1}=[]; else box{end+1} = [ min(x) min(y) max(x)-min(x)+1 max(y)-min(y)+1]; end end %%% additional code to display things for i=1:num, figure; subplot(121); colormap gray; imshow( imgs{i}); if ~isempty(box{i}) hold on; rr = rectangle( 'position', box{i}); set( rr, 'EdgeColor', 'r'); hold off; end subplot(122); imshow( imgs{i}.*uint8(repmat(dilated_image{i},[1 1 3]))); end </code></pre> <h2>Results</h2> <p><img src="https://i.stack.imgur.com/O0lOK.jpg" alt="results"></p> <p>High resolution results still <a href="http://georgepavlides.info/_uploads/christmas_tree_challenge_2013/all_HSV_LoG_results.jpg" rel="noreferrer"><strong>available here!</strong></a><br/> <strong><a href="http://georgepavlides.info/_uploads/christmas_tree_challenge_2013/all_HSV_LoG_results_more.jpg" rel="noreferrer">Even more experiments with additional images can be found here.</a></strong></p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload