Kitabı oku: «Мультимедийное Программирование OpenCV», sayfa 5
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_sharpen.jpg", IMREAD_GRAYSCALE);
CV_Assert(image.data);
float data[] = {
–1, -1, -1,
–1, 9, -1,
–1, -1, -1};
Mat mask(3, 3, CV_32F, data), sharpen;
filter(image, sharpen, mask);
sharpen.convertTo(sharpen, CV_8U);
namedWindow(“Original Image", WINDOW_AUTOSIZE);
namedWindow(“Sharpening Image", WINDOW_AUTOSIZE);
moveWindow("Original Image", 200, 200), moveWindow("Sharpening Image", 600, 200);
imshow("Original Image", image), imshow("Sharpening Image", sharpen);
waitKey();
return 0;
}
Обнаружение края / Edge Detection
•
В изображении край (edge) – это часть, где значение пикселя (pixel value) резко меняется
Hhh
•
Однородный оператор
– центральный пиксель 8 – дифференциальный расчет
●
Дифференциальный оператор
– центральный пиксель и пиксель на противоположной стороне и 4 дифференциальных вычисления (differential calculation)
Выход дифференциального оператора =
Однородный вывод оператора
Обнаружение края (однородный оператор) / Edge Detection (Homogeneous Operator)
// Edge Detection (Homogeneous Operator) Program
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
void homogenOp(Mat img, Mat& dst, int mask_size)
{
dst = Mat(img.size(), CV_8U, 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);
}
for (int i = 1; i < img.rows + 1; i++) {
ExtImg.at<float>(i, 0) = ExtImg.at<float>(i, 1);
ExtImg.at<float>(i, img.cols + 1) = ExtImg.at<float>(i, img.cols);
}
for (int j = 1; j < img.cols + 1; j++) {
ExtImg.at<float>(0, j) = ExtImg.at<float>(1, j);
ExtImg.at<float>(img.rows + 1, j) = ExtImg.at<float>(img.rows, j);
}
ExtImg.at<float>(0, 0) = ExtImg.at<float>(1, 1);
ExtImg.at<float>(0, img.cols + 1) = ExtImg.at<float>(1, img.cols);
ExtImg.at<float>(img.rows + 1, 0) = ExtImg.at<float>(img.rows, 1);
ExtImg.at<float>(img.rows + 1, img.cols + 1) = ExtImg.at<float>(img.rows, img.cols);
// next page continued....
Обнаружение края (однородный оператор) / Edge Detection (Homogeneous Operator)
for (int i = 0; i < img.rows; i++) {
for (int j = 0; j < img.cols; j++) {
float max = 0;
for (int u = 0; u < mask_size; u++) {
for (int v = 0; v < mask_size; v++) {
float difference = abs(ExtImg.at<float>(i+1, j+1) – ExtImg.at<float>(i+u, j+v));
if (difference > max)
max = difference;
}
}
dst.at<uchar>(i, j) = max;
}
}
}
int main()
{
Mat image = imread("../image/edge_test.jpg", IMREAD_GRAYSCALE);
CV_Assert(image.data);
Mat edge;
homogenOp(image, edge, 3);
namedWindow(“Original Image", WINDOW_AUTOSIZE);
namedWindow(“Homogen. Edge", WINDOW_AUTOSIZE);
moveWindow(“Original Image", 200, 200);
moveWindow("Homogen. Edge", 600, 200);
imshow(“Original Image", image);
imshow("Homogen. Edge", edge);
waitKey();
return 0;
}
Обнаружение края (Дифференциальный оператор) / Edge Detection (Differential Operator)
// Edge Detection (Differential Operator) Program
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
void differOp(Mat img, Mat& dst, int mask_size)
{
dst = Mat(img.size(), CV_8U, 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);
}
for (int i = 1; i < img.rows + 1; i++) {
ExtImg.at<float>(i, 0) = ExtImg.at<float>(i, 1);
ExtImg.at<float>(i, img.cols + 1) = ExtImg.at<float>(i, img.cols);
}
for (int j = 1; j < img.cols + 1; j++) {
ExtImg.at<float>(0, j) = ExtImg.at<float>(1, j);
ExtImg.at<float>(img.rows + 1, j) = ExtImg.at<float>(img.rows, j);
}
ExtImg.at<float>(0, 0) = ExtImg.at<float>(1, 1);
ExtImg.at<float>(0, img.cols + 1) = ExtImg.at<float>(1, img.cols);
ExtImg.at<float>(img.rows + 1, 0) = ExtImg.at<float>(img.rows, 1);
ExtImg.at<float>(img.rows + 1, img.cols + 1) = ExtImg.at<float>(img.rows, img.cols);
// next page continued....
// Edge Detection (Differential Operator) Program
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
void differOp(Mat img, Mat& dst, int mask_size)
{
dst = Mat(img.size(), CV_8U, 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);
}
for (int i = 1; i < img.rows + 1; i++) {
ExtImg.at<float>(i, 0) = ExtImg.at<float>(i, 1);
ExtImg.at<float>(i, img.cols + 1) = ExtImg.at<float>(i, img.cols);
}
for (int j = 1; j < img.cols + 1; j++) {
ExtImg.at<float>(0, j) = ExtImg.at<float>(1, j);
ExtImg.at<float>(img.rows + 1, j) = ExtImg.at<float>(img.rows, j);
}
ExtImg.at<float>(0, 0) = ExtImg.at<float>(1, 1);
ExtImg.at<float>(0, img.cols + 1) = ExtImg.at<float>(1, img.cols);
ExtImg.at<float>(img.rows + 1, 0) = ExtImg.at<float>(img.rows, 1);
ExtImg.at<float>(img.rows + 1, img.cols + 1) = ExtImg.at<float>(img.rows, img.cols);
// next page continued....
for (int i = 0; i < img.rows; i++) {
for (int j = 0; j < img.cols; j++) {
vector<float> mask;
for (int u = 0; u < mask_size; u++) {
for (int v = 0; v < mask_size; v++)
mask.push_back(ExtImg.at<float>(i + u, j + v));
}
float max = 0;
for (int k = 0; k <= mask_size; k++) {
float difference = abs(mask[k]-mask[8-k]);
if (difference > max) max = difference;
}
dst.at<uchar>(i, j) = max;
}
}
}
int main()
{
Mat image = imread("../image/edge_test.jpg", IMREAD_GRAYSCALE);
CV_Assert(image.data);
Mat edge;
differOp(image, edge, 3);
namedWindow(“Original Image", WINDOW_AUTOSIZE);
namedWindow(“Diff. Edge", WINDOW_AUTOSIZE);
moveWindow("Original Image", 200, 200), moveWindow("Diff. Edge", 600, 200);
imshow("Original Image", image), imshow("Diff. Edge", edge);
waitKey();
return 0;
}
Обнаружение краев (оператор маски Робертса/Собела) / Edge Detection (Roberts/Sobel Mask Operator)
●
Оператор маски Робертса
/ Roberts Mask Operator
163-iň suratyny alyp bilmedim.
●
Оператор Маски Собел (Оператор Маски Собел)
/
Sobel Mask Operator (Sobel Mask Operator)
Обнаружение края (оператор маски Робертса) / Edge Detection (Roberts Mask Operator)
// Edge Detection (Roberts Mask Operator)
// Using filter2D function of OpenCV
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
void differential(Mat image, Mat& dst, float data1[], float data2[])
{
Mat dst1, mask1(3, 3, CV_32F, data1);
Mat dst2, mask2(3, 3, CV_32F, data2);
filter2D(image, dst1, CV_32F, mask1, Point(-1, -1), 0, BORDER_REPLICATE);
filter2D(image, dst2, CV_32F, mask2, Point(-1, -1), 0, BORDER_REPLICATE);
// Point : filtering start point of kernel, 0 : value added to result
// BORDER_REPLICATE : image extension using border replication
magnitude(dst1, dst2, dst);
dst.convertTo(dst, CV_8U);
dst1 = abs(dst1);
dst2 = abs(dst2);
dst1.convertTo(dst1, CV_8U);
dst2.convertTo(dst2, CV_8U);
namedWindow(“Mask 1 Result", WINDOW_AUTOSIZE);
namedWindow("Mask 2 Result", WINDOW_AUTOSIZE);
moveWindow("Mask 1 Result", 200, 500);
moveWindow("Mask 2 Result", 700, 500);
imshow("Mask 1 Result", dst1);
imshow("Mask 2 Result", dst2);
}
// next page continued....
int main()
{
Mat image = imread("../image/edge_test1.jpg", IMREAD_GRAYSCALE);
CV_Assert(image.data);
float data1[] = {
-1, 0, 0,
0, 1, 0,
0, 0, 0
};
float data2[] = {
0, 0, -1,
0, 1, 0,
0, 0, 0
};
Mat dst;
differential(image, dst, data1, data2);
namedWindow(“Original Image", WINDOW_AUTOSIZE);
namedWindow(“Roberts Edge", WINDOW_AUTOSIZE);
moveWindow("Original Image", 200, 100);
moveWindow("Roberts Edge", 700, 100);
imshow("Original Image”, image);
imshow("Roberts Edge", dst);
waitKey();
return 0;
}
Обнаружение края (оператор маски Собеля) / Edge Detection (Sobel Mask Operator)
// Edge Detection (Sobel Mask Operator)
// Using filter2D and Sobel function of OpenCV
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
void differential(Mat image, Mat& dst, float data1[], float data2[])
{
Mat dst1, mask1(3, 3, CV_32F, data1);
Mat dst2, mask2(3, 3, CV_32F, data2);
filter2D(image, dst1, CV_32F, mask1, Point(-1, -1), 0, BORDER_REPLICATE);
filter2D(image, dst2, CV_32F, mask2, Point(-1, -1), 0, BORDER_REPLICATE);
magnitude(dst1, dst2, dst);
dst.convertTo(dst, CV_8U);
convertScaleAbs(dst1, dst1);
convertScaleAbs(dst2, dst2);
namedWindow("dst1 – Vertical Mask", WINDOW_AUTOSIZE);
namedWindow("dst2 – Horiz. Mask", WINDOW_AUTOSIZE);
moveWindow("dst1 – Vertical Mask", 700, 100);
moveWindow("dst2 – Horiz. Mask", 700, 500);
imshow("dst1 – Vertical Mask", dst1);
imshow("dst2 – Horiz. Mask", dst2);
}
int main()
{
Mat image = imread("../image/edge_test1.jpg", IMREAD_GRAYSCALE);
CV_Assert(image.data);
// next page continued....
float data1[] = {
-1, 0, 1,
-2, 0, 2,
-1, 0, 1 };
float data2[] = {
-1, -2, -1,
0, 0, 0,
1, 2, 1 };
Mat dst, dst3, dst4;
differential(image, dst, data1, data2);
namedWindow(“Original Image", WINDOW_AUTOSIZE);
namedWindow(“Sobel Edge", WINDOW_AUTOSIZE);
moveWindow("Original Image", 200, 100);
moveWindow("Sobel Edge", 200, 500);
imshow("Original Image", image);
imshow("Sobel Edge", dst);
// Sobel Edge Detection using OpenCV Function
Sobel(image, dst3, CV_32F, 1, 0, 3); // 4th = 1 -> vertical mask (vertical edge)
Sobel(image, dst4, CV_32F, 0, 1, 3); // 5th = 1 -> horizontal mask (horizontal edge)
convertScaleAbs(dst3, dst3); // 3 -> kernal size
convertScaleAbs(dst4, dst4);
namedWindow("dst3 – vert._OpenCV", WINDOW_AUTOSIZE);
namedWindow("dst4 – horiz._OpenCV", WINDOW_AUTOSIZE);
moveWindow("dst3 – vert._OpenCV", 1200, 100);
moveWindow("dst4 – horiz._OpenCV", 1200, 500);
imshow("dst3 – vert.OpenCV", dst3), imshow("dst4 – horiz._OpenCV", dst4);
waitKey();
return 0;
}
Медианный фильтр / Median Filter
Медианный фильтр / Median Filter
–
После выравнивания значений соседних пикселей (neighbor pixel) в порядке возрастания выберите значение центра в качестве выходного значения
–
Используется для удаления импульсного шума (impulse noise), который имеет резкое изменение цвета, как искра(spark) на изображении (image)
// Median Filtering Program
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
void medianFilter(Mat img, Mat& dst, int size)
{
dst = Mat(img.size(), CV_8U, 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);
}
for (int i = 1; i < img.rows + 1; i++) {