fanfuhan OpenCV 教學118 ~ opencv-118-Grabcut圖像分割

fanfuhan OpenCV 教學118 ~ opencv-118-Grabcut圖像分割

fanfuhan OpenCV 教學118 ~ opencv-118-Grabcut圖像分割



資料來源: https://fanfuhan.github.io/

https://fanfuhan.github.io/2019/05/25/opencv-118/

GITHUB:https://github.com/jash-git/fanfuhan_ML_OpenCV


Grabcut是基於圖割(graph cut)實現的圖像分割算法,它需要用戶輸入一個bounding box作為分割目標位置,實現對目標與背景的分離/分割,這個跟KMeans與MeanShift等圖像分割方法有很大的不同,但是Grabcut分割速度快,效果好,支持交互操作,因此在很多APP圖像分割/背景虛化的軟件中可以看到其身影。


C++

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main(int argc, char** argv) {
	Mat src = imread("D:/images/master.jpg");
	if (src.empty()) {
		printf("could not load image...\n");
		return 0;
	}
	namedWindow("input", WINDOW_AUTOSIZE);
	imshow("input", src);

	Mat mask = Mat::zeros(src.size(), CV_8UC1);
	Rect rect(180, 20, 180, 220);
	Mat bgdmodel = Mat::zeros(1, 65, CV_64FC1);
	Mat fgdmodel = Mat::zeros(1, 65, CV_64FC1);
	grabCut(src, mask, rect, bgdmodel, fgdmodel, 5, GC_INIT_WITH_RECT);
	Mat result;
	for (int row = 0; row < mask.rows; row++) {
		for (int col = 0; col < mask.cols; col++) {
			int pv = mask.at<uchar>(row, col);
			if (pv == 1 || pv == 3) {
				mask.at<uchar>(row, col) = 255;
			}
			else {
				mask.at<uchar>(row, col) = 0;
			}
		}
	}
	bitwise_and(src, src, result, mask);
	imshow("grabcut result", result);
	waitKey(0);
	return 0;
 }

Python

"""
Grabcut图像分割
"""

import cv2 as cv
import numpy as np

src = cv.imread("images/master.jpg")
cv.imshow("input", src)

mask = np.zeros(src.shape[:2], dtype=np.uint8)
rect = (53, 12, 356, 622)
iterCount = 5
bgdmodel = np.zeros((1, 13 * iterCount), np.float64)
fgdmodel = np.zeros((1, 13 * iterCount), np.float64)

cv.grabCut(src, mask, rect, bgdmodel, fgdmodel, iterCount, mode=cv.GC_INIT_WITH_RECT)
mask2 = np.where((mask == 1) + (mask == 3), 255, 0).astype('uint8')
print(mask2.shape)
result = cv.bitwise_and(src, src, mask=mask2)

cv.imshow("result", result)
cv.waitKey(0)
cv.destroyAllWindows()

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *