opencv3.4获取图片特定颜色区域并进行替换

现需要对图像中的某区域进行颜色替换,效果如上图所示,左一为原图,中间位提取的紫色区域,右图为颜色替换结果,由于没有细致调参数所以效果表现不是很好,但是相关思路可以提供参考。代码如下:


#include <iostream>
#include <vector>

#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>

#define WINDOWS_NAME "混合图像"

using namespace std;
using namespace cv;



cv::Mat img1 = cv::imread("../TestChangeColor/test.jpg", 1);//
cv::Mat gray1,gray2,addWeightMat;
cv::Mat result2;
cv::Mat subMat= cv::Mat::zeros(img1.size(), CV_8UC1);
cv::Mat purpleMat;//二值图像
cv::Mat purpleToMorph;

int pThreshold = 80;
int pContrast =  12;

/*
 * 1.检测紫色区域---->判断是否有紫色区域
 * 2.提取紫色---->二值图像像素点位置
 * 3.颜色替换---->输出替换图
 *
 * */

void onThresholdValueChange(int ,void* tempMat)
{
    cv::Mat mat2 = *(cv::Mat*)tempMat;
    cv::Mat mat1 = mat2.clone();
    cv::Mat gray1;
    cv::cvtColor(mat1,gray1,CV_BGR2GRAY);

    for(int i = 0 ; i < img1.rows; i ++)
    {
        for(int j = 0 ; j < img1.cols; j ++)
        {
            if(purpleToMorph.at<uchar>(i,j) == 255)
            {
                float alpha = gray1.at<uchar>(i, j) - (float)pThreshold;
                if(alpha < 0) alpha = 0;
    //            float b = mat1.at<cv::Vec3b>(i, j)[0];
                float g = mat1.at<cv::Vec3b>(i, j)[1];
    //            float r = mat1.at<cv::Vec3b>(i, j)[2];
                g *= 1 + (alpha / 256.0) * pContrast;
                if(g > 255)
                    g = 255;
                mat1.at<cv::Vec3b>(i, j)[1] = g;
            }
        }
    }

    imshow(WINDOWS_NAME,mat1);

}


void onContrastValueChange(int ,void* tempMat)
{

    cv::Mat mat2 = *(cv::Mat*)tempMat;
    cv::Mat mat1 = mat2.clone();
    cv::Mat gray1;
    cv::cvtColor(mat1,gray1,CV_BGR2GRAY);

    for(int i = 0 ; i < mat1.rows; i ++)
    {
        for(int j = 0 ; j < mat1.cols; j ++)
        {
            if(purpleToMorph.at<uchar>(i,j) == 255)
            {
                float alpha = gray1.at<uchar>(i, j) - (float)pThreshold;
                if(alpha < 0) alpha = 0;
    //            float b = mat1.at<cv::Vec3b>(i, j)[0];
                float g = mat1.at<cv::Vec3b>(i, j)[1];
    //            float r = mat1.at<cv::Vec3b>(i, j)[2];
                g *= 1 + (alpha / 256.0) * pContrast;
//                g += 30 + (alpha / 100.0) * pContrast;
                if(g > 255)
                    g = 255;
                mat1.at<cv::Vec3b>(i, j)[1] = g;
            }
        }
    }

    imwrite("../TestChangeColor/result1.jpg",mat1);
    imshow(WINDOWS_NAME,mat1);
}

void testChangeColor()
{

    cv::resize(img1,img1,Size(400,400));
    namedWindow("src",CV_WINDOW_AUTOSIZE);
    imshow("src",img1);
    cv::Mat baseMat = cv::Mat::zeros(img1.size(), CV_8UC3);
    /*识别出紫色区域:RGB转HSV--->HSV空间能够非常直观的表达色彩的明暗,色调,以及鲜艳程度
     *
     * */
    cv::Mat hsvMat;
    cv::cvtColor(img1,hsvMat,CV_RGB2HSV);
    cv::cvtColor(img1,gray1,CV_BGR2GRAY);

//    imshow("hsv",hsvMat);
    namedWindow("gray",CV_WINDOW_AUTOSIZE);
    imshow("gray",gray1);
    Scalar lowPurple = Scalar(110, 43, 46);//紫色对应的HSV最小值Scalar(125, 43, 46)
    Scalar highPurple = Scalar(155, 255, 255);//紫色对应的HSV最大值(155, 255, 255)

    cv::inRange(hsvMat,lowPurple,highPurple,purpleMat);


    cv::Mat kernel = getStructuringElement(MORPH_RECT,Size(15,15),Point(-1,-1));
    morphologyEx(purpleMat,purpleToMorph,MORPH_OPEN,kernel,Point(-1,-1));


    cv::resize(purpleToMorph,purpleToMorph,Size(400,400));
    namedWindow("purple",CV_WINDOW_AUTOSIZE);
    imshow("purple",purpleToMorph);

    /*
     * int createTrackbar
     * (
        const string& trackerbarname, //创建滑动条的名字
        const string winname, //所在窗口的名字
        int* value, //一个指向整型的指针,表示滑块的位置,在创建时,滑块的初始位置就是该变量当前的值。
        int count, //滑块可以达到的最大位置的值。滑块最小位置的值始终为0
        TrackbarCallback onChange=0, //这个参数和回调函数有关,这是一个指向回调函数地址的指针,当滑动条上位置改变的时候,回调函数就会再次执行,
        void* userdata=0//用户传给回调函数的数据,用来处理轨迹条事件。如果使用的value实参是全局变量,可以不去管userdata参数。
        );
*/
    namedWindow(WINDOWS_NAME,CV_WINDOW_AUTOSIZE);//createTrackbar之前定义才能出滑块
    createTrackbar("Threshold Value",WINDOWS_NAME,&pThreshold,255,onThresholdValueChange,&img1);
    onThresholdValueChange(pThreshold,&img1);

    createTrackbar("Contrast Value",WINDOWS_NAME,&pContrast,255,onContrastValueChange,&img1);
    onContrastValueChange(pContrast,&img1);

    cv::waitKey(0);

}


int main(int argc, char *argv[])
{

    testChangeColor();

    return 0;
}

参考文献

[1] 【OpenCV】HSV颜色识别-HSV基本颜色分量范围

完整代码下载

  • 8
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值