% This function generates a binary mask from the input video, ensuring that the object with the largest area is maintained across all video frames

% INPUT PARAMETERS:
% - "readerobj": Input video. If "a1" > 0, it corresponds to an MxNxC matrix containing all video frames excluding the section removed by the ROI.
% - "FreVi":     Video capture frame rate (FPS / frames per second).
% - "minP":      Minimum pixel value used to separate the background from the object of interest.
% - "maxP":      Maximum pixel value considered to isolate the object of interest from reflections or intensity saturation.
% - "area":      Area threshold; any object with an area smaller than this value will be eliminated.
% - "aref":      Flag variable. If its value is greater than 0, it removes any object touching the borders (walls) of the image.
% - "a1":        Flag variable indicating whether a manual ROI was applied.

% OUTPUT VARIABLE:
% - "Maskim":    Resulting binary mask of MxN dimensions.
% NOTE ON DEPENDENT FUNCTIONS:
% For this script to work properly, the following function must be located in the same folder:
%   FucCordenada("CenX", "CenY", "LimMaxX", "LimMaxY", "Area")
% This subfunction is used to obtain the limits of the four corners with respect to the centroid (X,Y) and the object's area.

function Maskim= FucMaskIm(readerobj,FreVi,minP,maxP,area,aref,a1)
se = strel('disk',5);
% Determine frame count and sample frame source
if a1==0
    N=readerobj.NumberOfFrames;
    FreVi=round(readerobj.FrameRate);
    im=read(readerobj,FreVi+1);
else
    im=readerobj(:,:,FreVi+1);
    h3=size(readerobj);
    N=h3(3);
end
im=im2gray(im);
h1=size(im);
impix=zeros(h1(1),h1(2));   
Maskim=zeros(h1(1),h1(2));
% Accumulate object pixels across sampled frames
for i=FreVi+1:N
    if a1==0
        imr=read(readerobj, i);
    else 
        imr=readerobj(:,:,i);
    end
    imr=im2gray(imr);
    imr=double(imr);
    we=find(imr<=minP);
    we2=find(imr>=maxP);
    imr(we)=0;
    imr(we2)=0;
    we3=find(imr>0);
    imr(we3)=255;
    imr=imbinarize(imr);
    % Clean noise with erosion then dilation (opening)
    imb=imerode(imr,se);
    imb=imdilate(imb,se);
    % Optionally remove objects touching image borders
    if aref==1
        imb = imclearborder(imb,4);
    end
    we4=find(imb>0);
    % Mark pixels present in any sampled frame
    impix(we4)=255;
end
imref=imbinarize(impix);
imref = imfill(imref,'holes');
s = regionprops(imref,'centroid','Area');
hs=size(s);
% Remove small regions by zeroing their corner bounding boxes
for i=1:hs(1)
    ar=sqrt(s(i).Area);
    pos=s(i).Centroid;
    if ar<=area
        [mnX,mxX,mnY,mxY]= FucCordenada(pos(1),pos(2),h1(2),h1(1),round(ar));
        imref(mnY:mxY,mnX:mxX)=0;
    end
end  
% Morphological cleanup: shrink then expand to merge components
imref=imerode(imref,se);
imref=imdilate(imref,se);
imref=imdilate(imref,se);
imref=imdilate(imref,se);
we5=find(imref>0);
% Transfer nonzero pixels into output mask
Maskim(we5)=255;
end