[C ++] change the background color based on the OpenCV photo

#include <opencv2 / opencv.hpp> 
#include <the iostream> the using namespace STD;
 the using namespace CV; void ChangeImgBG (); 
Mat HandleImgData (Mat & IMG);
 / * 
background picture alternative 
knowledge: the watershed segmentation, Gaussian blur 
processing step : dividing data assembling -KMeans - background subtraction - generating the mask - Fuzzy - output * / void ChangeImgBG () 
{ const char * = Win1 " WINDOW1 " ;
     const char * Win2 = " Window2 " ;
     const char * WIN3 = " window3 "

  




       ;
     Const  char * win4 = " window4 " ;
     const  char * WIN5 = " window5 " ;
     const  char * win6 = " window6 " ; 
    namedWindow (Win1, WINDOW_AUTOSIZE); // create the window Win1 
    namedWindow (Win2, WINDOW_AUTOSIZE); // create window Win2 
    namedWindow (WIN3, WINDOW_AUTOSIZE); // create the window WIN3 
    namedWindow (win4, WINDOW_AUTOSIZE); // create the window win4 
    namedWindow (win5, WINDOW_AUTOSIZE); // create the window win5
    namedWindow (win6, WINDOW_AUTOSIZE); // window win6 create 

    Mat img1, img2; 
    // Load picture 
    img1 = imread ( " pph.jpg " );
     IF (img1.empty ()) 
    { 
        cout << " Image not found .. . " << endl; 
        exit ( 0 ); // if the picture does not exist, the program exits 
    } 
    IMG2 = img1.clone ();
     // display the original image 
    imshow (Win1, IMG1);
     // assembling data 
    Mat Points = HandleImgData ( IMG1); 

    // Kmeans processing 
    int numCluster = 4;
    Mat labels;
    Mat centers;
    TermCriteria termCriteria = TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, 10, 0.1);

    kmeans(points, numCluster, labels, termCriteria, 3, KMEANS_PP_CENTERS, centers);
    //遮罩
    Mat mask = Mat::zeros(img1.size(), CV_8UC1);
    int index = img1.rows * 2 + 2;
    int cindex = labels.at<int>(index, 0);//背景设置为0
    int height = img1.rows;
    int width = img1.cols;

    for (int row = 0; row < height; row++)
    {
        for (int col = 0; col < width; col++)
        {
            index = row * width + col;
            int label = labels.at<int>(index, 0);
            if (label == cindex)
            {
                img2.at<Vec3b>(row, col)[0] = 0;
                img2.at<Vec3b>(row, col)[1] = 0;
                img2.at<Vec3b>(row, col)[2] = 0;
                mask.at<uchar>(row, col) = 0;
            }
            else
            {
                mask.at<uchar>(row, col) = 255;
            }
        }
    }

    //腐蚀
    Mat k = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
    erode(mask, mask, k);
    imshow(win4, mask);

    //高斯模糊
    GaussianBlur(mask, mask, Size(3, 3), 0, 0);
    imshow(win5, mask);

    //通道混合
    RNG rng(12345);


    //背景颜色调整
    Vec3b color;
    /*color[0] = rng.uniform(255, 255);
    color[1] = rng.uniform(255, 255);
    color[2] = rng.uniform(255, 255);*/
    color[0] = 255;
    color[1] = 255;
    color[2] = 255;

    Mat result(img1.size(), img1.type());

    double d1 = 0.0;
    int r = 0, g = 0, b = 0;
    int r1 = 0, g1 = 0, b1 = 0;
    int r2 = 0, g2 = 0, b2 = 0;


    for (int row = 0; row < height; row++)
    {
        for (int col = 0; col < width; col++)
        {
            int m = mask.at<uchar>(row, col);
            if (m == 255)
            {
                result.at<Vec3b>(row, col) = img1.at<Vec3b>(row, col);//前景
            }
            else if (m == 0)
            {
                result.at<Vec3b>(row, col) = color;//背景
            }
            else
            {
                d1 = m / 255.0;
                b1 = img1.at<Vec3b>(row, col)[0];
                g1 = img1.at<Vec3b>(row, col)[1];
                r1 = img1.at<Vec3b>(row, col)[2];

                b2 = color[0];
                g2 = color[1];
                r2 = color[2];

                b = b1 * d1 + b2 * (1.0 - d1);
                g = g1 * d1 + g2 * (1.0 - d1);
                r = r1 * d1 + r2 * (1.0 - d1);

                result.at<Vec3b>(row, col)[0] = b;
                result.at<Vec3b> (Row, COL) [ . 1 ] = G; 
                result.at <Vec3b> (Row, COL) [ 2 ] = R & lt; 
            } 
        } 
    } 

    // Output 
    imshow (Win2, mask); 
    imshow (WIN3, IMG2) ; 
    imshow (win6, Result); 
    // save the processed image 
    imwrite ( " pph_bg_white.jpg " , Result); 
} 

// assembled sample data 
Mat HandleImgData (Mat & IMG) 
{ 
    int width = img.cols;
     int height = img.rows;
     int count1 is = width * height;
    int channels1 = img.channels();

    Mat points(count1, channels1, CV_32F, Scalar(10));
    int index = 0;
    for (int row = 0; row < height; row++)
    {
        for (int col = 0; col < width; col++)
        {
            index = row * width + col;
            Vec3b bgr = img.at<Vec3b>(row, col);
            points.at<float>(index, 0) = static_cast<int>(bgr[0]);
            points.at<float>(index, 1) = static_cast<int>(bgr[1]);
            points.at<float>(index, 2) = static_cast<int>(bgr[2]);
        }
    }
    return points;
}

int main()
{
    ChangeImgBG();

    waitKey(0);
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/lightmonster/p/11454002.html