0

I am trying to select only the eyes that were segmented from some face images. Here is one example of one binary image.

enter image description here

The problem is that I want to get each eye of the image, putting them centered in a fixed size squared image. In this case, there will be two images with the eye centered on a fixed nxn squared image.

I tried to check the following post How to extract white region in an image but it seems to work only in one big part of a binary image. How to do that in my case?

mad
  • 2,677
  • 8
  • 35
  • 78
  • 1
    if you want a bounding box and area (number of pixels), use connected components labeling (with statistics) or findContours. the question/answer you found should already have given you the information you need. – Christoph Rackwitz Dec 15 '21 at 09:50
  • 2
    What do you call centered eyes precisely ? –  Dec 15 '21 at 12:03
  • 1
    Do you want the centroid of the white region or the center of the black iris area inside the white region for the centers? – fmw42 Dec 16 '21 at 17:35
  • @fmw42 the second one. There is already an answer to that. Thank you! – mad Dec 17 '21 at 14:03

2 Answers2

3

I find the center of all white areas and save the nxn squared image on this location.

import cv2
from matplotlib import pyplot as plt
import numpy as np

img = cv2.imread('vQZyz.png',0)

im_bin = cv2.threshold(img.copy(), 127, 255, cv2.THRESH_BINARY)[1]
num_labels, labels_im = cv2.connectedComponents(img)

n = 100 #size of the ROI
n //= 2

for i in range(1,labels_im.max()+1): #for each white area
  #find the center of the area
  x = (min(np.where(labels_im == i)[0]) + max(np.where(labels_im == i)[0]))//2
  y = (min(np.where(labels_im == i)[1]) + max(np.where(labels_im == i)[1]))//2

  ROI = img[max(0,x-n):min(x+n,img.shape[0]),
            max(0,y-n):min(y+n,img.shape[1])]
  
  cv2.imwrite("ROI"+str(i)+"_"+str(2*n)+"x"+str(2*n)+".png", ROI) #save the ROI

output with n = 100 :

ROI1_100x100

ROI2_100x100

1

Basically, you can calculate your contour area and take reference areas. So, you can limit your contour you want to. Afterwards, you can choose your related ROI.

You can use code at below:

#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>
using namespace cv;
using namespace std;
Mat src_gray;
int thresh = 100;
RNG rng(12345);
void thresh_callback(int, void *);
int main(int argc, char **argv)
{
    Mat src = imread("../input/eyes.png");
    if (src.empty())
    {
        cout << "Could not open or find the image!\n"
             << endl;
        cout << "Usage: " << argv[0] << " <Input image>" << endl;
        return -1;
    }
    cvtColor(src, src_gray, COLOR_BGR2GRAY);
    blur(src_gray, src_gray, Size(5, 5));
    const char *source_window = "Source";
    namedWindow(source_window);
    imshow(source_window, src);
    const int max_thresh = 255;
    createTrackbar("Canny thresh:", source_window, &thresh, max_thresh, thresh_callback);
    thresh_callback(0, 0);
    waitKey();
    return 0;
}
void thresh_callback(int, void *)
{
    Mat canny_output;
    Canny(src_gray, canny_output, thresh, thresh * 2);
    vector<vector<Point>> contours;
    vector<Vec4i> hierarchy;
    findContours(canny_output, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE);
    Mat drawing = Mat::zeros(canny_output.size(), CV_8UC3);
    cv::Mat roi1, roi2;
    int count = 0;
    for (size_t i = 0; i < contours.size(); i++)
    {
        if (contourArea(contours[i]) > 1300)
        {
            count++;
            std::cout << " Area: " << contourArea(contours[i]) << std::endl;
            Scalar color = Scalar(rng.uniform(0, 256), rng.uniform(0, 256), rng.uniform(0, 256));
            drawContours(drawing, contours, (int)i, color, 2, LINE_8, hierarchy, 0);
            Rect box = boundingRect(contours[i]);
            std::cout << " Box: " << box << std::endl;

            if (count == 1)
            {
                roi1 = src_gray(box);
            }
            else if (count == 2)
            {
                roi2 = src_gray(box);
            }
        }
    }

    std::cout << " " << std::endl;
    imshow("Contours", drawing);
    imshow("roi1", roi1);
    imshow("roi2", roi2);
}
DrBobs
  • 76
  • 6