Loe raamatut: «Мультимедийное Программирование OpenCV», lehekülg 4

Font:

      exit(1);

}

Rect roi(135, 95, 20, 15);

Mat roi_img = image(roi);

Mat image_roi(Size(roi_img.cols * 10, roi_img.rows * 10), CV_8U, Scalar(0));

// next page continued....

for (int i = 0; i < roi_img.rows; i++) {

for (int j = 0; j < roi_img.cols; j++) {

      for (int k = 0; k < 10; k++) {

       for (int m = 0; m < 10; m++)

            image_roi.at<uchar>(i*10+k, j*10+m) = roi_img.at<uchar>(i, j);

      }

}

}

imshow("image_roi", image_roi);

cout << "[roi_img] =" << endl;

      cout << roi_img << endl;

rectangle(image, roi, Scalar(255), 1);

imshow("image", image);

waitKey();

return 0;

}

● 

Выход /

Output



Сложение/вычитание значения яркости изображения / Addition/Subtraction of Image Brightness Value


// Addition/Subtraction of Image Brightness Value

#include <opencv2/opencv.hpp>

using namespace cv;

using namespace std;

int main()

{

Mat image = imread("../image/bright.jpg", IMREAD_GRAYSCALE);

CV_Assert(!image.empty());

Mat dst1 = image + 100;      // Automatic saturate_cast

Mat dst2 = image – 100;      // Automatic saturate_cast

Mat dst3 = 255 – image;      // Image negative transform

Mat dst4(image.size(), image.type());

Mat dst5(image.size(), image.type());

// next page continued....


for (int i = 0; i < image.rows; i++) {

      for (int j = 0; j < image.cols; j++) {

            dst4.at<uchar>(i, j) = image.at<uchar>(i, j) + 100;

            dst5.at<uchar>(i, j) = 255 – image.at<uchar>(i, j);

      }

}

imshow(“Original Image", image);

imshow("dst1 – Brighter", dst1);

imshow("dst2 – Darker", dst2);

imshow("dst3 – Inversion", dst3);

imshow("dst4 – Brighter", dst4);

imshow("dst5 – Darker", dst5);

waitKey();

return 0;

}

//dst4.at<uchar>(i, j) = saturate_cast<uchar>(image.at<uchar>(i, j) + 100);


Гистограмма / Histogram

• 

График, показывающий количество значений яркости каждого пикселя (pixel) в image (изображении)

• 

Горизонтальная ось – значение яркости пикселя

• 

Вертикальная ось – частота (frequency) яркости (brightness) каждого пикселя (pixel)

• 

Image вы можете узнать распределение значений яркости пикселей для


• 

Предоставленная Open CV Histogram Calculation Function (функция вычисления гистограммы)

calcHist (img, nimg, chn, mask, hist, dims, histsize, range)

– 

img: исходный массив изображений (тип данных CV_8U или CV_32F)

– 

nimg: номера оригинальных изображений

– 

chn: список каналов

– 

mask: mask array (Выполнять расчеты только для позиций с ненулевым значением)

– 

hist: гистограмма, сохраняющая массив результатов вычислений

– 

dims: номер измерения гистограммы

– 

histsize: размер массива гистограммы каждого измерения

– 

range: диапазон значений пикселей гистограммы


Расчет гистограммы / Histogram Calculation


// Histogram Calculation

#include <opencv2/opencv.hpp>

using namespace cv;

using namespace std;

void calc_Histo(const Mat& image, Mat& hist, int bins, int range_max = 256)

{

int histSize[] = { bins };

float range[] = { 0, (float)range_max };

      int channels[] = { 0 };

const float* ranges[] = { range };

calcHist(&image, 1, channels, Mat(), hist, 1, histSize, ranges); // OpenCV

}

int main()

{

Mat image = imread("../image/pixel_test.jpg", IMREAD_GRAYSCALE);

CV_Assert(!image.empty());

Mat hist, hist_img;

calc_Histo(image, hist, 256);

cout << hist.t() << endl;

imshow("image", image);

waitKey();

return 0;

}


● 

Выход

/ Output



Рисование гистограммы / Histogram Drawing


// Histogram Drawing Program

#include <opencv2/opencv.hpp>

using namespace cv;

using namespace std;

void calc_Histo(const Mat& image, Mat& hist, int bins, int range_max = 256)

{

int histSize[] = { bins };

float range[] = { 0, (float)range_max };

int channels[] = { 0 };

const float* ranges[] = { range };

calcHist(&image, 1, channels, Mat(), hist, 1, histSize, ranges);

}

void draw_histo(Mat hist, Mat &hist_img, Size size = Size(256, 200))

{

hist_img = Mat(size, CV_8U, Scalar(255));

normalize(hist, hist, 0, hist_img.rows, NORM_MINMAX);

// next page continued....


for (int i = 0; i < hist.rows; i++){

Point2f pt1 = Point2f(i, 0);

Point2f pt2 = Point2f((i + 1), hist.at <float>(i));

if (pt2.y > 0)

      rectangle(hist_img, pt1, pt2, Scalar(0), -1);

}

flip(hist_img, hist_img, 0);

}

int main()

{

Mat image = imread("../image/lena_std.tif", IMREAD_GRAYSCALE);

CV_Assert(!image.empty());

Mat hist, hist_img;

calc_Histo(image, hist, 256);

draw_histo(hist, hist_img);

imshow(“Histogram Image”, hist_img);

imshow(“Image", image);

waitKey();

return 0;

}



Растяжение гистограммы / Histogram Stretching
















// Histogram Stretching Program

#include <opencv2/opencv.hpp>

using namespace cv;

using namespace std;

void calc_Histo(const Mat& image, Mat& hist, int bins, int range_max = 256)

{

int histSize[] = { bins };

float range[] = { 0, (float)range_max };

int channels[] = { 0 };

const float* ranges[] = { range };

calcHist(&image, 1, channels, Mat(), hist, 1, histSize, ranges);

}

void draw_histo(Mat hist, Mat &hist_img, Size size = Size(256, 200))

{

hist_img = Mat(size, CV_8U, Scalar(255));

normalize(hist, hist, 0, hist_img.rows, NORM_MINMAX);

for (int i = 0; i < hist.rows; i++) {

Point2f pt1 = Point2f(i, 0);

Point2f pt2 = Point2f((i+1), hist.at <float>(i));

if (pt2.y > 0)

rectangle(hist_img, pt1, pt2, Scalar(0), -1);

}

flip(hist_img, hist_img, 0);

}

void search_valueIdx(Mat hist, int &low_value, int &high_value)

{

int i;

for (i = 0; i < hist.rows; i++) {

if (hist.at<float>(i) > 0)

break;

}

low_value = i;

// next page continued....


for (i = hist.rows-1; i > 0; i–){

      if (hist.at<float>(i) > 0)

break;

}

high_value = i;

}

int main()

{

Mat image = imread("../image/Lenna-histo_str.tif", 0);

CV_Assert(!image.empty());

Mat hist, hist_dst, hist_img, hist_dst_img;

int histsize = 256, ranges = 256;

calc_Histo(image, hist, histsize, ranges);

draw_histo(hist, hist_img);

int low_value, high_value;

search_valueIdx(hist, low_value, high_value);

cout << "high_value = " << high_value << endl;

cout << "low_value = " << low_value << endl;

int d_value = high_value – low_value;

Mat dst = (image – low_value) * (255.0 / d_value);

calc_Histo(dst, hist_dst, histsize, ranges);

draw_histo(hist_dst, hist_dst_img);

imshow("Original Image", image);

imshow("Hist. Stretch. Image", dst);

imshow("Hist. of Origin", hist_img);

imshow("Hist. of Stretch. Image", hist_dst_img);

waitKey();

return 0;

}


Выравнивание гистограммы / Histogram Equalization

• 

Применяется к изображениям с широким распределением гистограммы (Histogram), но с распределением контраста, смещенным в одном направлении


• 

[Шаг 1] Расчет гистограммы

• 

[Шаг 2] Расчет накопленной суммы гистограммы



• 

[Шаг 3] Нормализация накопленной суммы

: Общее количество пикселей

: Максимальное значение яркости пикселей


● 

Шаг 1

– Расчет гистограммы


ㅔㅑㅔㅑㅑ

a) яркость пикселей


изображение

изображение


image

(b) histogram

яркость пикселей


● 

Шаг 2

– Расчет накопленной суммы гистограммы


(a)Гистограмма


яркость пикселей


(b) Накопленная сумма


● 

Шаг 3

– Нормализация накопленной суммы

– 

n[i]=sum[i]*(1/16)*7


j Нормализованная гистограмма




(b) гистограмма


(a) входное изображение







// Histogram Equalization Program

#include <opencv2/opencv.hpp>

using namespace cv;

using namespace std;

void calc_Histo(const Mat& image, Mat& hist, int bins, int range_max = 256)

{

int histSize[] = { bins };

float range[] = { 0, (float)range_max };

int channels[] = { 0 };

const float* ranges[] = { range };

calcHist(&image, 1, channels, Mat(), hist, 1, histSize, ranges);

}

void draw_histo(Mat hist, Mat &hist_img, Size size = Size(256, 200))

{

hist_img = Mat(size, CV_8U, Scalar(255));

Mat hist2;

normalize(hist, hist2, 0, hist_img.rows, NORM_MINMAX);

for (int i = 0; i < hist2.rows; i++) {

Point2f pt1 = Point2f(i, 0);

Point2f pt2 = Point2f((i+1), hist2.at <float>(i));

if (pt2.y > 0)

rectangle(hist_img, pt1, pt2, Scalar(0), -1);

}

flip(hist_img, hist_img, 0);

}

void create_hist(Mat img, Mat &hist, Mat &hist_img)

{

int histsize = 256, range = 256;

calc_Histo(img, hist, histsize, range);

draw_histo(hist, hist_img);

}

// next page continued....


int main()

{

Mat image = imread("../image/Ave.tif", 0);

CV_Assert(!image.empty());

Mat hist, dst1, dst2, hist_img, hist_img1, hist_img2;

create_hist(image, hist, hist_img);

Mat accum_hist = Mat(hist.size(), hist.type(), Scalar(0));

accum_hist.at<float>(0) = hist.at<float>(0);

for (int i = 1; i < hist.rows; i++)

accum_hist.at<float>(i) = accum_hist.at<float>(i – 1) + hist.at<float>(i);

accum_hist /=(image.rows*image.cols);;

accum_hist *= 255;

dst1 = Mat(image.size(), CV_8U);

for (int i = 0; i < image.rows; i++) {

for (int j = 0; j < image.cols; j++) {

int idx = image.at<uchar>(i, j);

      dst1.at<uchar>(i, j) = (uchar)accum_hist.at<float>(idx);

}

}

create_hist(dst1, hist, hist_img1);

// Using Histogram Equalization of OpenCV Function

equalizeHist(image, dst2);

create_hist(dst2, hist, hist_img2);

imshow(“image", image), imshow("img_hist", hist_img);

imshow("dst1-User", dst1), imshow("User_hist", hist_img1);

imshow("dst2-OpenCV", dst2), imshow("OpenCV_hist", hist_img2);

waitKey();

return 0;

}


7. Обработка свертки с использованием OpenCV / Convolution

Processing using OpenCV

Обработка свертки / Convolution Processing

• 

Изображение обрабатывается с использованием метода свертки (convolution technique), включая ассоциацию с соседним пикселем (neighbor pixel) пикселя

• 

использование Mask (= Kernel, Window, Filter)


Маска(М)


Соседние пиксели


Входное изображение(f)


Текущий пиксели


Pixel

Выходной пиксель


Выходное изображение (г)


Сумма всех умножений


Умножение маски и соседних пикселей


Размытие / Blurring

• 

Как внести постепенные изменения в резкость изменения значения пикселя (pixel value)

• 

Обработка свертки с использованием маски размытия.

• 

Маска размытия


Входное изображение


(a) Входное изображение


(b) Размытое изображение


// Blurring Program

#include <opencv2/opencv.hpp>

using namespace cv;

using namespace std;

void filter(Mat img, Mat& dst, Mat mask)

{

dst = Mat(img.size(), CV_32F, Scalar(0));

// Image Extension (using 3 x 3 Mask)

Mat ExtImg(img.rows+2, img.cols+2, CV_32F);

for (int i = 0; i < img.rows; i++) {

for (int j = 0; j < img.cols; j++)

ExtImg.at<float>(i + 1, j + 1) = img.at<uchar>(i, j); // center

}

for (int i = 1; i < img.rows+1; i++) {

ExtImg.at<float>(i, 0) = ExtImg.at<float>(i, 1);      // Left line

ExtImg.at<float>(i, img.cols + 1) = ExtImg.at<float>(i, img.cols); // Right line

}

for (int j = 1; j < img.cols+1; j++){

ExtImg.at<float>(0, j) = ExtImg.at<float>(1, j);      // Upper line

ExtImg.at<float>(img.rows + 1, j) = ExtImg.at<float>(img.rows, j); // Bottom line

}

ExtImg.at<float>(0, 0) = ExtImg.at<float>(1, 1); // Upper left corner

ExtImg.at<float>(0, img.cols+1) = ExtImg.at<float>(1, img.cols); // Upper right corner

ExtImg.at<float>(img.rows+1, 0) = ExtImg.at<float>(img.rows, 1); // Bottom left corner

ExtImg.at<float>(img.rows+1, img.cols+1) = ExtImg.at<float>(img.rows, img.cols); // Bottom right

                                     // corner

// next page continued....


for (int i = 0; i < img.rows; i++) {

for (int j = 0; j < img.cols; j++) {

float sum = 0;

for (int u = 0; u < mask.rows; u++) {

      for (int v = 0; v < mask.cols; v++)

       sum += ExtImg.at<float>(i + u, j + v) * mask.at<float>(u, v);

}

dst.at<float>(i, j) = sum;

}

}

}

int main()

{

Mat image = imread("../image/filter_blur.jpg", IMREAD_GRAYSCALE);

CV_Assert(image.data);

float data[] = {

1 / 9.f, 1 / 9.f, 1 / 9.f,

1 / 9.f, 1 / 9.f, 1 / 9.f,

1 / 9.f, 1 / 9.f, 1 / 9.f };

Mat mask(3, 3, CV_32F, data), blur;

filter(image, blur, mask);

blur.convertTo(blur, CV_8U);

namedWindow(“Original Image", WINDOW_AUTOSIZE);

namedWindow(“Blurring", WINDOW_AUTOSIZE);

moveWindow(“Original Image", 200, 200), moveWindow(“Blurring", 600, 200);

imshow(“Original image", image), imshow(“Blurring", blur);

waitKey();

return 0;

}


Заточка / Sharpening

• 

Разница между соседними пикселями (neighbor pixel) заставляет их чувствовать себя резкими

• 

Детали изображения могут быть подчеркнуты, а контраст яркости (brightness contrast) увеличен на краевой (edge) части

• 

Заточка маски


(a) Входное изображение


(b) Резкое изображение


// Sharpening Program

#include <opencv2/opencv.hpp>

using namespace cv;

Vanusepiirang:
12+
Ilmumiskuupäev Litres'is:
26 juuli 2024
Kirjutamise kuupäev:
2024
Objętość:
125 lk 126 illustratsiooni
Õiguste omanik:
Автор
Allalaadimise formaat:
epub, fb2, fb3, ios.epub, mobi, pdf, txt, zip