2015-11-13 4 views
3

Я знаю, что можно выровнять гистограмму изображения, как:OpenCV, уравнять гистограмму контура изображения

equalizeHist(image, image); 

, и если я хочу, я могу определить КОРОЛЬ и уравнять только этот КОРОЛЬ на картинке:

Mat aux3 = image.clone(); 
equalizeHist(image(Rect(0,100, 200,200)), aux3(Rect(0,100, 200,200))); 

то, что я хотел бы сделать сейчас (и я не знаю, если это возможно), чтобы определить Руа (контур) с использованием вектора точек (сорте :: вектор контура) и уравнять это roi (этот roi не всегда будет прямоугольником)

Итак, вопрос здесь:

Можно ли выравнивать часть изображения, которая не является прямоугольником, используя функции openCV?

ответ

4

В OpenCV нет встроенной функции для выполнения выравнивания гистограммы с помощью маски. Тем не менее вы можете написать свой собственный.


Получить изображение в оттенках серого:

// Load image 
Mat3b img = imread("path_to_image"); 

// Convert to grayscale 
Mat1b gray; 
cvtColor(img, gray, COLOR_BGR2GRAY); 

enter image description here

Форма маски из ваших пунктов:

// Your vector of points 
vector<Point> pts = { Point(300, 180), Point(450, 150), Point(600, 200), Point(650, 350), Point(300,300) }; 

// Create the mask 
Mat1b mask(img.rows, img.cols, uchar(0)); 
vector<vector<Point>> ptsarray{pts}; 
fillPoly(mask, ptsarray, Scalar(255)); 

enter image description here

Позвоните пользовательскую функцию equalizeHistWithMask, что выравнивать изображение с маской:

// Equalize with mask 
Mat1b equalized; 
equalizeHistWithMask(gray, equalized, mask); 

enter image description here

Вот полный код для справки, с функцией equalizeHistWithMask:

#include <iostream> 
#include <vector> 
#include <algorithm> 
#include <opencv2/opencv.hpp> 
using namespace std; 
using namespace cv; 

void equalizeHistWithMask(const Mat1b& src, Mat1b& dst, Mat1b mask = Mat1b()) 
{ 
    int cnz = countNonZero(mask); 
    if (mask.empty() || (cnz == src.rows*src.cols)) 
    { 
     equalizeHist(src, dst); 
     return; 
    } 

    dst = src.clone(); 

    // Histogram 
    vector<int> hist(256,0); 
    for (int r = 0; r < src.rows; ++r) { 
     for (int c = 0; c < src.cols; ++c) { 
      if (mask(r, c)) { 
       hist[src(r, c)]++; 
      } 
     } 
    } 

    // Cumulative histogram 
    float scale = 255.f/float(cnz); 
    vector<uchar> lut(256); 
    int sum = 0; 
    for (int i = 0; i < hist.size(); ++i) { 
     sum += hist[i]; 
     lut[i] = saturate_cast<uchar>(sum * scale); 
    } 

    // Apply equalization 
    for (int r = 0; r < src.rows; ++r) { 
     for (int c = 0; c < src.cols; ++c) { 
      if (mask(r, c)) { 
       dst(r, c) = lut[src(r,c)]; 
      } 
     } 
    } 
} 

int main() 
{ 
    // Load image 
    Mat3b img = imread("path_to_image"); 

    // Convert to grayscale 
    Mat1b gray; 
    cvtColor(img, gray, COLOR_BGR2GRAY); 

    // Your vector of points 
    vector<Point> pts = { Point(300, 180), Point(450, 150), Point(600, 200), Point(650, 350), Point(300,300) }; 

    // Create the mask 
    Mat1b mask(img.rows, img.cols, uchar(0)); 
    vector<vector<Point>> ptsarray{pts}; 
    fillPoly(mask, ptsarray, Scalar(255)); 

    // Equalize with mask 
    Mat1b equalized; 
    equalizeHistWithMask(gray, equalized, mask); 

    imshow("Gray", gray); 
    imshow("Mask", mask); 
    imshow("Equalized", equalized); 
    waitKey(); 

    return 0; 
} 

Кредиты

код основан на this вопрос о answers.opencv.org

+0

мне это нравится. Спасибо! – user1705996

Смежные вопросы