从二值图像中提取白色区域

Posted

技术标签:

【中文标题】从二值图像中提取白色区域【英文标题】:Extract white regions from binary images 【发布时间】:2022-01-18 12:07:50 【问题描述】:

我试图只选择从一些面部图像中分割出来的眼睛。这是一张二值图像的示例。

问题是我想获取图像的每只眼睛,将它们放在固定大小的正方形图像的中心。在这种情况下,将有两张眼睛以固定的 nxn 平方图像为中心的图像。

我尝试查看以下帖子How to extract white region in an image,但它似乎只适用于二进制图像的很大一部分。在我的情况下如何做到这一点?

【问题讨论】:

如果您想要一个边界框和区域(像素数),请使用连接组件标记(带有统计信息)或 findContours。您找到的问题/答案应该已经为您提供了所需的信息。 什么叫居中眼睛? 你想要白色区域的质心还是白色区域内的黑色虹膜区域的中心作为中心? @fmw42 第二个。已经有答案了。谢谢! 【参考方案1】:

我找到所有白色区域的中心并将 nxn 平方图像保存在此位置。

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

n = 100 的输出:

【讨论】:

【参考方案2】:

基本上,您可以计算轮廓区域并获取参考区域。所以,你可以限制你想要的轮廓。之后,您可以选择相关的投资回报率。

您可以使用以下代码:

#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);

【讨论】:

以上是关于从二值图像中提取白色区域的主要内容,如果未能解决你的问题,请参考以下文章

自适应阈值化操作:adaptiveThreshold()函数

数字图像处理-图像形态学处理-颗粒提取

深度好文Python图像处理之物体标识与面积测量

使用python从二进制图像中裁剪感兴趣区域

python库skimage 绘制二值图像的凸壳(convex hull)

如何区分二值图像和灰度图像?