最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++ OpenCV實(shí)現(xiàn)灰度圖蒙版GrayMask的示例代碼

 更新時間:2022年05月07日 11:39:22   作者:翟天保Steven  
這篇文章主要為大家詳細(xì)介紹了如何利用C++和OpenCV實(shí)現(xiàn)灰度圖蒙版GrayMask,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)或工作有一定參考價值,需要的可以參考一下

需求說明

在對圖像進(jìn)行處理時,經(jīng)常會有這類需求:想對感興趣區(qū)域進(jìn)行掩膜處理,只操作掩膜內(nèi)數(shù)據(jù),此時需要搭配掩膜繪制功能,并在繪制過程中希望能區(qū)分掩膜區(qū)和非掩膜區(qū);除了掩膜本身的線條以外,還希望掩膜內(nèi)圖像是原色,掩膜外圖像的顏色進(jìn)行一定調(diào)整;通常可以采用圖像透明化或者色彩單通道加深的方式實(shí)現(xiàn)。

比如對三通道的圖像,可以將掩膜外數(shù)據(jù)的紅通道數(shù)值提高,此時該部分圖像就會偏紅色,如下圖1所示。

圖1 顏色加深的蒙版效果

但是針對灰度圖,因?yàn)閳D像數(shù)據(jù)本身就是單通道的,就不能借用顏色通道或者透明通道了;有一個基礎(chǔ)的辦法是將非掩膜區(qū)數(shù)據(jù)同時加減某個數(shù)值,這種方法簡單但有一個弊端,比如我加了50,那原圖200-255之間的數(shù)值都將變?yōu)?55,這樣就損壞了原圖的某些特征信息。為此,我們采用非線性的算法將其進(jìn)行較為合理的數(shù)值調(diào)整。

下面介紹具體實(shí)現(xiàn)流程。

具體流程

1)構(gòu)造非線性參數(shù)。其中n為函數(shù)輸入的參數(shù),范圍在-100到100;a、b、k為算法參數(shù),公式見下。

n = min(max(n, -100), 100);
int k = 4;
float b = n / 100.f / k;
float a = 1.0f + k * b;

2)參照上式,對掩膜外數(shù)據(jù)進(jìn)行如下處理。

float temp = pow(float(in[j]) / 255.f, 1.0f / a) * (1.0 / (1 + b));

3)temp的數(shù)值需要進(jìn)行校準(zhǔn),因?yàn)榛叶戎等绻莡char型,范圍在0-255之間,校準(zhǔn)后乘上255,即可得到算法計(jì)算的結(jié)果。

if (temp > 1.0f)
    temp = 1.0f;
if (temp < 0.0f)
    temp = 0.0f;
uchar utemp = uchar(255 * temp);
r[j] = utemp;

4)掩膜內(nèi)數(shù)值保持不變。

r[j] = in[j];

5)輸出圖像,完成。

功能函數(shù)

// 灰度圖蒙版
cv::Mat GrayMask(cv::Mat input, cv::Mat mask, int n)
{
    // 通道判斷
    if (input.channels() != 1)
    {
        return input;
    }
    
    // 非線性參數(shù)
    // 當(dāng)n=100時,非掩膜區(qū)呈灰色;當(dāng)n=0時,非掩膜區(qū)無變化;當(dāng)n=-100時,非掩膜區(qū)黑色
    // n越小,非掩膜區(qū)越暗,n越大,非掩膜區(qū)越灰
    // 目的是區(qū)分非掩膜區(qū)和掩膜區(qū)
    n = min(max(n, -100), 100);
    int k = 4;
    float b = n / 100.f / k;
    float a = 1.0f + k * b;
 
    // 蒙版處理
    cv::Mat result = cv::Mat::zeros(input.size(), input.type());
    for (int i = 0; i < input.rows; ++i)
    {
        uchar *m = mask.ptr<uchar>(i);
        uchar *in = input.ptr<uchar>(i);
        uchar *r = result.ptr<uchar>(i);
        for (int j = 0; j < input.cols; ++j)
        {
            if (m[j] == 0)
            {
                float temp = pow(float(in[j]) / 255.f, 1.0f / a) * (1.0 / (1 + b));
                if (temp > 1.0f)
                    temp = 1.0f;
                if (temp < 0.0f)
                    temp = 0.0f;
                uchar utemp = uchar(255 * temp);
                r[j] = utemp;
            }
            else {
                r[j] = in[j];
            }
        }
    }
    return result;
}

C++測試代碼

#include <iostream>
#include <unordered_map>
#include <unordered_set>
#include <stdio.h>
#include <io.h>
#include <chrono> 
#include <time.h>
#include <stdio.h>
#include <direct.h>
#include <ctime>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
 
using namespace std;
using namespace cv;
 
cv::Mat GrayMask(cv::Mat input, cv::Mat mask, int n);
 
int main()
{
    // 讀取灰度圖
    cv::Mat src = imread("1.png",0);
    // 繪制掩膜
    cv::Mat mask = cv::Mat::zeros(src.size(), CV_8UC1);
    cv::circle(mask, cv::Point(src.cols / 2, src.rows / 2), 100, cv::Scalar(255), -1);
    // 灰度圖蒙版
    cv::Mat result = GrayMask(src, mask, 100);
    // 結(jié)果顯示
    imshow("src", src);
    imshow("result", result);
    waitKey(0);
    system("pause");
    return 0;
}
 
// 灰度圖蒙版
cv::Mat GrayMask(cv::Mat input, cv::Mat mask, int n)
{
    // 通道判斷
    if (input.channels() != 1)
    {
        return input;
    }
    
    // 非線性參數(shù)
    // 當(dāng)n=100時,非掩膜區(qū)呈灰色;當(dāng)n=0時,非掩膜區(qū)無變化;當(dāng)n=-100時,非掩膜區(qū)黑色
    // n越小,非掩膜區(qū)越暗,n越大,非掩膜區(qū)越灰
    // 目的是區(qū)分非掩膜區(qū)和掩膜區(qū)
    n = min(max(n, -100), 100);
    int k = 4;
    float b = n / 100.f / k;
    float a = 1.0f + k * b;
 
    // 蒙版處理
    cv::Mat result = cv::Mat::zeros(input.size(), input.type());
    for (int i = 0; i < input.rows; ++i)
    {
        uchar *m = mask.ptr<uchar>(i);
        uchar *in = input.ptr<uchar>(i);
        uchar *r = result.ptr<uchar>(i);
        for (int j = 0; j < input.cols; ++j)
        {
            if (m[j] == 0)
            {
                float temp = pow(float(in[j]) / 255.f, 1.0f / a) * (1.0 / (1 + b));
                if (temp > 1.0f)
                    temp = 1.0f;
                if (temp < 0.0f)
                    temp = 0.0f;
                uchar utemp = uchar(255 * temp);
                r[j] = utemp;
            }
            else {
                r[j] = in[j];
            }
        }
    }
    return result;
}

測試效果

圖2 原圖

圖3 灰度圖蒙版效果

如果函數(shù)有什么可以改進(jìn)完善的地方,非常歡迎大家指出,一同進(jìn)步何樂而不為呢~

到此這篇關(guān)于C++ OpenCV實(shí)現(xiàn)灰度圖蒙版GrayMask的示例代碼的文章就介紹到這了,更多相關(guān)C++ OpenCV灰度圖蒙版內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • QT6中添加串口模塊SerialPort的實(shí)現(xiàn)

    QT6中添加串口模塊SerialPort的實(shí)現(xiàn)

    本文主要介紹了QT6中添加串口模塊SerialPort的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-09-09
  • 基于QT制作一個TCPServer與TCPClient的通信

    基于QT制作一個TCPServer與TCPClient的通信

    這篇文章主要為大家詳細(xì)介紹了如何基于QT制作一個TCPServer與TCPClient的通信,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-12-12
  • 詳細(xì)分析C++ 數(shù)據(jù)封裝和數(shù)據(jù)抽象

    詳細(xì)分析C++ 數(shù)據(jù)封裝和數(shù)據(jù)抽象

    這篇文章主要介紹了C++ 數(shù)據(jù)封裝和數(shù)據(jù)抽象的的相關(guān)資料,文中代碼非常詳細(xì),幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-06-06
  • Seesion在C++服務(wù)端的使用方法

    Seesion在C++服務(wù)端的使用方法

    這篇文章主要介紹了Seesion在C++服務(wù)端是怎么使用的?本文給出了解決方案和實(shí)例代碼供大家參考,需要的朋友可以參考下
    2020-02-02
  • C++中的按位與&、按位與或|、按位異或^運(yùn)算符詳解

    C++中的按位與&、按位與或|、按位異或^運(yùn)算符詳解

    這篇文章主要介紹了C++中的按位與&、按位與或|、按位異或^運(yùn)算符,是C++入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2016-01-01
  • C++頭文件algorithm中的函數(shù)功能詳解

    C++頭文件algorithm中的函數(shù)功能詳解

    這篇文章主要介紹了C++頭文件algorithm中的函數(shù)功能詳解,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-04-04
  • 完全掌握C++編程中構(gòu)造函數(shù)使用的超級學(xué)習(xí)教程

    完全掌握C++編程中構(gòu)造函數(shù)使用的超級學(xué)習(xí)教程

    這篇文章主要介紹了C++中的構(gòu)造函數(shù),包括C++11標(biāo)準(zhǔn)中的新特性的介紹,十分推薦!需要的朋友可以參考下
    2016-01-01
  • Objective-C限制函數(shù)調(diào)用的頻率詳解

    Objective-C限制函數(shù)調(diào)用的頻率詳解

    這篇文章主要給大家介紹了關(guān)于Objective-C限制函數(shù)調(diào)用的頻率的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-12-12
  • 詳解C++中的指針、數(shù)組指針與函數(shù)指針

    詳解C++中的指針、數(shù)組指針與函數(shù)指針

    本文從初學(xué)者的角度,深入淺出地講解C++中的指針、數(shù)組指針與函數(shù)指針,對最?;煜囊脗鬟f、值傳遞和指針傳遞做了區(qū)處,需要的朋友可以參考下
    2015-07-07
  • C++初始化數(shù)組的幾種常見方法(簡單易懂)

    C++初始化數(shù)組的幾種常見方法(簡單易懂)

    本文介紹了C++中數(shù)組的初始化方法,包括一維數(shù)組和二維數(shù)組的初始化,以及用new動態(tài)初始化數(shù)組,在C++11及以上版本中,還提供了使用std::array和std::vector進(jìn)行靜態(tài)和動態(tài)初始化的方式,需要的朋友可以參考下
    2025-02-02

最新評論

阜城县| 辽阳县| 建昌县| 繁昌县| 文安县| 威宁| 黎城县| 绥江县| 罗甸县| 彭州市| 宁波市| 久治县| 鹤山市| 垣曲县| 延长县| 湖南省| 建始县| 垣曲县| 建昌县| 班玛县| 温州市| 宜春市| 犍为县| 中阳县| 灵宝市| 永州市| 台北市| 土默特右旗| 辽阳县| 宁化县| 五华县| 上虞市| 邵武市| 上高县| 辽宁省| 宁陕县| 湖口县| 德惠市| 社旗县| 伽师县| 资溪县|