#!/usr/bin/env lua

--[[
  =======================
    Morfologice operace  
  =======================

  ===============
  potrebne funkce
  ===============

    cv.LoadImage()        Nacitani obrazku ze souboru
    cv.CloneImage()       Vytvori kopii obrazku
    cv.Get2D()            Nacteni vektoru hodnot z obrazku.
    cv.CvtColor()         Konverze barev v obrazku
    cv.Threshold()        Prahovani obrazu
    cv.Dilate()           Dilatace obrazu
    cv.Erode()            Eroze obrazu
    cv.MorphologyEx()     Morfologicke operace obrazu
    dilatation()          uzivatelska funkce realizujici dilataci obrazu
    
]]

local cv=require('luacv')

function dilatation(img)
  if (not img) then error("dilatation(src_img,out_img)") end
  if (img.nChannels~=1) then
    -- Provedte konverzi obrazu img do odstinu sedi pomoci OpenCV funkce a parametru cv.CV_BGR2GRAY
    -- vysledek ulozte zpet do promenne img
    cv.CvtColor(img,img,cv.CV_BGR2GRAY);
  end

  -- Provedte prahovani obrazu out do out tak pomoci knihovni funkce s parametry prahu 120, 255 a cv.CV_THRESH_BINARY
  cv.Threshold(img,img,120,255,cv.CV_THRESH_BINARY);

  for i=0,img.width-1 do 
    for j=0,img.height-1 do
      -- Ulozte do promenne scalar prvek matice out na pozicich i,j
      local scalar=cv.Get2D(img,i,j)
      if (scalar.val[0]==255) then
        if (i~=0) then
          cv.Set2D(img,i-1,j,cv.Scalar(255));
        else
          if (i~=img.width-1) then
            cv.Set2D(img,i+1,j,cv.Scalar(255));
          end
        end
        cv.Set2D(img,i,j,cv.Scalar(255));
      end
    end
  end
end

-- Nactete zdrojovy obrazek biohazard.png do promenne img a pouzijte parametr cv.CV_LOAD_IMAGE_GRAYSCALE 
-- pro nacteni v odstinech sedi
img=cv.LoadImage((arg[1]~=nil and arg[1] or "biohazard.png"),cv.CV_LOAD_IMAGE_GRAYSCALE);
if (not img) then error("can't open file") end

-- Vytvorte kopii obrazu img do promenne copy
-- !!!! prirazeni   copy=img    je pouze melka kopie resp. ukazatel na img !!!
copy=cv.CloneImage(img);

-- Zavolejte uzivatelskou funkci realizujici dilataci obrazu
dilatation(copy); 
cv.ShowImage("dilatation",copy);

se=cv.CreateStructuringElementEx(3,1,1,0,cv.CV_SHAPE_RECT);
cv.Dilate(img,copy,se);
cv.ShowImage("Dilate",copy);
cv.Erode(img,copy,se,3);
cv.ShowImage("Erode",copy);

-- Provedte erozi obrazu img do obrazku copy pomoci strukturniho elementu se a po 3 iterace
cv.Erode(img,copy,se);
cv.Dilate(copy,copy,se);
cv.ShowImage("Erode&Dilate",copy);
-- Provedte morf. operaci otevreni vstupniho obrazu img do copy pomoci knihovni funkce, strukturniho elementu se, parametru cv.CV_MOP_OPEN 
-- a docasneho uloziste nil
cv.MorphologyEx(img,copy,nil,se,cv.CV_MOP_OPEN);
cv.ShowImage("Open",copy);

-- Provedte morf. operaci uzavreni pomoci kombinace Dilatece a Eroze obrazu img se strukturnim elementem se do obrazu copy.
cv.Dilate(img,copy,se);
cv.Erode(copy,copy,se);
cv.ShowImage("Dilate&Erode",copy);
cv.MorphologyEx(img,copy,nil,se,cv.CV_MOP_CLOSE);
cv.ShowImage("Close",copy);

cv.WaitKey();

cv.ReleaseImage(img);
cv.ReleaseImage(copy);
cv.ReleaseStructuringElement(se);
cv.DestroyAllWindows();
