Concrete bubble quantification for aesthetic classification

Exposed concrete must meet several requirements. Technological, structural and functional requirements are already standardized and designers refer to various Belgian and European standards.

The WTCB -CSTC (1) is standardizing aesthetic requirements of exposed concrete. These requirements relate to the texture, the number and size of the bubbles and the homogeneity of the color. This standard is an extension of the standard EN 206-1 , NBN B 15-001 and DIN EN 13670 .

The next image processing intends to measure the surface proportion of bubbles less than 2 mm, bubbles of 2 to 15 mm and bubbles over 15 mm ( defects) . According to the surface percentage of bubbles of 2 to 15 mm, it will be standard, high quality or high quality.

Concrete_Bubbles_600

0-2mm Bubbles in blue, 2-15mm bubbles in green, defaults in red. 

Click on the image to see the animated gif

The threshold used the Otsu algorithm optimized to cut bimodal (black and white) distribution of pixels.

Nevertheless to give good result the image has to be cleaned of non-uniform lighting and non-uniform concrete texture and color.

This is done by removing the background from the image. This background is provided by a morphological closing and better by a morphological erosion followed by a reconstruction (2).

Morphological closing

Morphological closing

Morphological erosion followed by a reconstruction.

Morphological erosion followed by a reconstruction.

Background corrected image

Background corrected image

Matlab code :

function [Sum_0_2, Sum_2_15, Sum_15_max] = GetConcretePorosity( image_path )
%  GetConcretePorosity
%  Computes the Porosity of concrete surface
%  Norm definition :
%  Standard Concrete : < 1,9% of 2-15mm bubbles;
%  HT Concrete : < 0,6% of 2-15mm bubbles
%  THT Concrete : <0,3% of 2-15mm bubbles
%  Usage:
%  [Sum_0_2, Sum_2_15, Sum_15_max] = ...
%  GetConcretePorosity('C:/Image-Acquisition/Bulles/Fotos/P1080135.JPG');

  % 1 - read the image
  Im_Color = imread(image_path);
  crop_option = 0;
  if crop_option == 1
    [Im_Color] = imcrop(Im_Color);
  end
  % rgb2gray converts RGB images to grayscale by eliminating the hue and
  % saturation information while retaining the luminance
  Im_Gray = rgb2gray(Im_Color);

  % 2 - read the resolution
  % note : 72dpi means 1 pixel = 25.4/72 mm = 0,35 mm
  info=imfinfo(image_path);
  XResolution = info.XResolution;
  Area_2mm = int32((3.1416/4)*(2*XResolution/25.4)^2);
  Area_15mm = int32((3.1416/4)*(15*XResolution/25.4)^2);

  % 3 - remove the background
  % remove what is smaller than 15mm : 15 x 72 / 25.4 pixels
  cutoff_size_mm = 15;
  SE_size = (cutoff_size_mm*XResolution/25.4)/2;
  %structuring_element = strel('disk', 20);
  structuring_element = strel('disk', double(uint8(SE_size)));

  remove_option = 2;
  if remove_option == 1
    Im_Closed = imclose(Im_Gray, structuring_element);
    Im_Corrected = imadjust(Im_Closed - Im_Gray);
  else
    Im_Gray_Complement = imcomplement(Im_Gray);
    Im_Marker = imerode(Im_Gray_Complement, structuring_element);
    Im_Reconstructed = imreconstruct(Im_Marker, Im_Gray_Complement);
    Im_Closed = imcomplement(Im_Reconstructed);
    Im_Corrected = imadjust(Im_Closed - Im_Gray);
  end

  %figure;
  %imshow(imcomplement(Im_Corrected));

  % 4 - the segmentation
  % The graythresh function uses Otsu's method, which chooses the threshold
  % to minimize the intraclass variance of the black and white pixels.
  level = graythresh(Im_Corrected);
  Im_Segmented = im2bw(Im_Corrected,level);
  Im_Segmented = imfill(Im_Segmented,'holes');
  % Remove particle smaller than 2mm with bwareaopen :
  % BW2 = bwareaopen(BW, P) removes from a binary image all connected
  % components (objects) that have fewer than P pixels
  % Im_Segmented = imclose(Im_Segmented, 15);

  cc = bwconncomp(Im_Segmented, 8);
  cc.NumObjects;

  labeled = labelmatrix(cc);
  % RGB_label = label2rgb(labeled, @spring, 'c', 'shuffle');
  % figure, imshow(RGB_label);

  graindata = regionprops(cc, 'basic');
  regions_areas = [graindata.Area];

  % 5 - make 3 groups of bubbles 0-2, 2-15, 15-max mm
  % sort the areas then the indexes
  [grain_areas, label_idx] = sort(regions_areas);
  [label_idx_s, label_idx_s_idx] = sort(label_idx);

  % remove the background region
  % grain_areas(end) = [];

  index_2mm = -1;
  index_15mm = -1;
  for i = 1:length(grain_areas)
    if all([grain_areas(i)>Area_2mm, index_2mm == -1])
        index_2mm = i;
    end
    if all([grain_areas(i)>Area_15mm, index_15mm == -1])
        index_15mm = i;
    end
  end

  % 6 - Create a animated gif
  Im_Color_Overlay = Im_Color;
  [Width, Height] = size(Im_Segmented);
  for j=1:Height
    for i=1:Width
      if labeled(i, j) ~= 0
        label_ij = labeled(i, j);
        label_idx_ij = label_idx_s_idx(label_ij);
        % Im_Color(i,j,:) = [255, 0, 255];
        if label_idx_ij < index_2mm
          Im_Color_Overlay(i,j,3) = 255;
        elseif label_idx_ij < index_15mm
          Im_Color_Overlay(i,j,2) = 255;
        else
          Im_Color_Overlay(i,j,1) = 255;
        end
      end
    end
  end

  filename = 'C:/Image-Acquisition/Concrete_Bubbles.gif';
  [Im_Color_Overlay_256, Im_Color_Overlay_Map] = ...
      rgb2ind(Im_Color_Overlay, 256);
  Im_Color_Overlay_256(:,:,1,2) = rgb2ind(Im_Color, Im_Color_Overlay_Map);
  imwrite(Im_Color_Overlay_256, Im_Color_Overlay_Map, filename, 'DelayTime', 1, ...
          'LoopCount', inf);

  %imwrite(Im_Color_Overlay_256, Im_Color_Overlay_Map, filename, 'gif', ...
  %        'DelayTime', 1, 'Loopcount',inf);
  %imwrite(Im_Color_Overlay_256, Im_Color_Overlay_Map, filename, 'gif', ...
  %        'WriteMode', 'append');

  figure, imshow(Im_Color);

  % 7 output histograms and surfaces ratio
  grain_areas = grain_areas(index_2mm:index_15mm);
  grain_size = sqrt(grain_areas/3.1416);
  x_bins = [0, 2, 15, 50];
  figure; s(1) = subplot(2,1,1); s(2) = subplot(2,1,2);
  hist(s(1), grain_size, x_bins);
  hist(s(2), grain_size, 20);

  Sum_0_2 = sum(regions_areas(1:index_2mm))/(Width*Height);
  Sum_2_15 = sum(regions_areas(index_2mm:index_15mm))/(Width*Height);
  Sum_15_max = sum(regions_areas(index_15mm:length(grain_areas)))/(Width*Height);

end

(1) The WTCB -CSTC is a research institute funded primarily by 90000 Belgian companies representing all construction trades , which leads scientific and technical research for the benefit of its members, providing technical advice and contributing to innovation in order to improve the competitiveness of these.

(2) Morphological Grayscale Reconstruction in Image Analysis: Applications and Ecient Algorithms, Luc Vincent. 

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Vous pouvez utiliser ces balises et attributs HTML : <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>