Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to realize background Separation by OpenCV

2025-03-31 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article mainly shows you how to achieve background separation in OpenCV. The content is simple and easy to understand and the organization is clear. I hope it can help you solve your doubts. Let Xiaobian lead you to study and learn this article "How to achieve background separation in OpenCV".

realization principle

Image background separation is one of the common image processing methods, belonging to the category of image segmentation. How to extract the background region optimally lies in two difficulties:

segmentation of background and foreground. In view of this difficulty, background color is obtained as reference value through human-computer interaction and other methods, and reasonable threshold is set in combination with root mean square difference to realize foreground extraction, which is called mask on PS; in the extraction process, foreground pixels may be lost, and the foreground interior can be filled completely by opening and closing operation or extracting external contour lines.

Fusion of foreground edge contour regions. If you can't fuse well, you can see obvious signs of misprint, so fusion is a critical step. First, the mask area (mask) for mean filtering, its edge area will generate between 0-255 buffer area; Second, through the proportional distribution of pixel points in the buffer area color, I fixed the proportion of 0.3 foreground background 0.7, because the background is monochromatic area, background proportion is high, can make the buffer area color tends to the background area, and achieve a better transition; Finally, mask is 0 area background color, mask is 255 area unchanged.

At this point, the image is segmented and background separation is completed. The C++ implementation code is as follows.

Function Code//Background Separation cv::Mat BackgroundSeparation(cv::Mat src, Inputparama input){ cv::Mat bgra, mask; //Convert to BGRA format with transparency, 4 channels cvtColor(src, bgra, COLOR_BGR2BGRA); mask = cv::Mat::zeros(bgra.size(), CV_8UC1); int row = src.rows; int col = src.cols; //abnormal value correction input.p.x = max(0, min(col, input.p.x)); input.p.y = max(0, min(row, input.p.y)); input.thresh = max(5, min(100, input.thresh)); input.transparency = max(0, min(255, input.transparency)); input.size = max(0, min(30, input.size)); //determine background color uchar ref_b = src.at(input.p.y, input.p.x)[0]; uchar ref_g = src.at(input.p.y, input.p.x)[1]; uchar ref_r = src.at(input.p.y, input.p.x)[2]; //Calculate mask area (mask) for (int i = 0; i

< row; ++i) { uchar *m = mask.ptr(i); uchar *b = src.ptr(i); for (int j = 0; j < col; ++j) { if ((geiDiff(b[3*j],b[3*j+1],b[3*j+2],ref_b,ref_g,ref_r)) >

input.thresh) { m[j] = 255; } } } //Find the outline, the role is to fill the black hole inside the outline vector contour; vector hierarchy; // RETR_TREE extracts all contours in a mesh structure, CHAIN_APPROX_NONE gets every pixel of the contour findContours(mask, contour, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_NONE); drawContours(mask, contour, -1, Scalar(255), FILLED,4); //closed operation cv::Mat element = getStructuringElement(MORPH_ELLIPSE, Size(5, 5)); cv::morphologyEx(mask, mask, MORPH_CLOSE, element); //Mask filtering, for edge blur cv::blur(mask, mask, Size(2 * input.size+1, 2 * input.size + 1)); //color change for (int i = 0; i < row; ++i) { uchar *r = bgra.ptr(i); uchar *m = mask.ptr(i); for (int j = 0; j < col; ++j) { //The area with mask 0 is the standard background area if (m[j] == 0) { r[4 * j] = uchar(input.color[0]); r[4 * j + 1] = uchar(input.color[1]); r[4 * j + 2] = uchar(input.color[2]); r[4 * j + 3] = uchar(input.transparency); } //The area not equal to 0 and not equal to 255 is the contour area (edge area) and needs blurring. else if (m[j] != 255) { //Color the edges proportionally int newb = (r[4 * j] * m[j] * 0.3 + input.color[0] * (255 - m[j])*0.7) / ((255 - m[j])*0.7+ m[j] * 0.3); int newg = (r[4 * j+1] * m[j] * 0.3 + input.color[1] * (255 - m[j])*0.7) / ((255 - m[j])*0.7 + m[j] * 0.3); int newr = (r[4 * j + 2] * m[j] * 0.3 + input.color[2] * (255 - m[j])*0.7) / ((255 - m[j])*0.7 + m[j] * 0.3); int newt = (r[4 * j + 3] * m[j] * 0.3 + input.transparency * (255 - m[j])*0.7) / ((255 - m[j])*0.7 + m[j] * 0.3); newb = max(0, min(255, newb)); newg = max(0, min(255, newg)); newr = max(0, min(255, newr)); newt = max(0, min(255, newt)); r[4 * j] = newb; r[4 * j + 1] = newg; r[4 * j + 2] = newr; r[4 * j + 3] = newt; } } } return bgra;}C++ test code #include #include #include using namespace cv;using namespace std; //input parameters struct Inputparama { int thresh = 30; //Background recognition threshold, the smaller the value, the larger the area of recognition non-background area, need to have a suitable range, currently 5-60 int transparency = 255; //background color transparency, 255 is solid, 0 is transparent int size = 7; //edge blur parameter of non-background area. The larger the value, the more obvious the degree of edge blur. cv::Point p = cv::Point(0, 0); //Background color sampling points, which can be obtained through human-computer interaction, or the default (0,0) point color can be used as background color. cv::Scalar color = cv::Scalar(255, 255, 255);//background color}; cv::Mat BackgroundSeparation(cv::Mat src, Inputparama input); //Compute difference RMS int geiDiff(uchar b,uchar g,uchar r,uchar tb,uchar tg,uchar tr){ return int(sqrt(((b - tb)*(b - tb) + (g - tg)*(g - tg) + (r - tr)*(r - tr))/3));} int main(){ cv::Mat src = imread("111.jpg"); Inputparama input; input.thresh = 100; input.transparency = 255; input.size = 6; input.color = cv::Scalar(0, 0, 255); clock_t s, e; s = clock(); cv::Mat result = BackgroundSeparation(src, input); e = clock(); double dif = e - s; cout

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report