-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathimproc.cpp
More file actions
172 lines (156 loc) · 4.34 KB
/
improc.cpp
File metadata and controls
172 lines (156 loc) · 4.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
#include <iostream>
#include <math.h>
#include "C:\OpenCV2.2\include\opencv2\opencv.hpp"
#include "improc.h"
improc::improc()
{
inter = cv::INTER_CUBIC;
kernel_size = 5;
k_size_harf = (int)(kernel_size / 2);
}
improc::improc(int interpolate)
{
inter = interpolate;
kernel_size = 5;
k_size_harf = (int)(kernel_size / 2);
}
int improc::resizeImage(const cv::Mat src, cv::Mat &dst)
{
scale_x = (double)dst.cols / (double)src.cols;
scale_y = (double)dst.rows / (double)src.rows;
src_size = src.size();
dst_size = dst.size();
for (int i = 0; i < dst.rows; i++) {
for (int j = 0; j < dst.cols; j++) {
cv::Mat weighted;
cv::Rect src_rect = _getTargetRect(cv::Point(j, i));
weighted = src(src_rect).mul(_getKernel(cv::Point(j, i), src_rect));
cv::Scalar sum = cv::sum(weighted);
dst.at<cv::Vec3f>(i, j) = cv::Vec3f(sum(0), sum(1), sum(2));
}
}
return 0;
}
/**
* _getKernel 畳み込みを行うカーネルを取得する
*d
* point cv::Point 出力画像の座標
* src_rect cv::Rect 入力画像の畳み込みを行う範囲
* return cv::Mat 入力画像に対する重みマップ
*
**/
cv::Mat improc::_getKernel(cv::Point point, cv::Rect src_rect)
{
cv::Mat kernel = cv::Mat::zeros(src_rect.height, src_rect.width, CV_32FC3);
cv::Point2f center2f = _dstPointToSrc(point);
double sum = 0., weight;
for (int i = 0; i < src_rect.height; i++) {
for (int j = 0; j < src_rect.width; j++) {
double distance_x = abs(center2f.x - (double)(j + src_rect.x));
double distance_y = abs(center2f.y - (double)(i + src_rect.y));
sum += weight =_distanceToWeight(distance_x, distance_y);
kernel.at<cv::Vec3f>(i, j) = cv::Vec3f::all(weight);
}
}
kernel.convertTo(kernel, CV_32FC3, 1./sum);
return kernel;
}
/**
* _getKernel 畳み込みを行うカーネルを取得する
*
* point cv::Point 出力画像の座標
* return cv::Mat 入力画像に対する重みマップ
*
**/
cv::Mat improc::_getKernel(cv::Point point)
{
return _getKernel(point, _getTargetRect(point));
}
/**
* _getTargetRect 入力画像のカーネルとの畳み込みを行う範囲を取得する
*
* point cv::Point 出力画像の座標
* return cv::Rect 入力画像の畳み込みを行う範囲
*
**/
cv::Rect improc::_getTargetRect(cv::Point point)
{
cv::Rect rect;
cv::Point center = (cv::Point)_dstPointToSrc(point);
if (center.x - k_size_harf < 0) {
rect.x = 0;
rect.width = kernel_size + (center.x - k_size_harf);
} else if (center.x + k_size_harf >= src_size.width) {
rect.x = center.x - k_size_harf;
rect.width = src_size.width - rect.x;
} else {
rect.x = center.x - k_size_harf;
rect.width = kernel_size;
}
if (center.y - k_size_harf < 0) {
rect.y = 0;
rect.height = kernel_size + (center.y - k_size_harf);
} else if (center.y + k_size_harf >= src_size.height) {
rect.y = center.y - k_size_harf;
rect.height = src_size.height - rect.y;
} else {
rect.y = center.y - k_size_harf;
rect.height = kernel_size;
}
return rect;
}
/**
* _dstPointToSrc 出力画像の座標を入力画像の対応する座標に変換する
*
* point cv::Point 出力画像の座標
* return cv::Point2f 入力画像の対応する少数精度座標
*
**/
cv::Point2f improc::_dstPointToSrc(cv::Point point)
{
double x = point.x / scale_x + 0.5 / scale_x - 0.5;
double y = point.y / scale_y + 0.5 / scale_y - 0.5;
return cv::Point2f(x, y);
}
/**
* _distanceToWeight 距離を重み係数に変換する
*
* dist_x double x軸の距離
* dist_y double y軸の距離
* interpolate int フィルタの種類
* return double 重み係数
*
**/
double improc::_distanceToWeight(double dist_x, double dist_y, int interpolate)
{
if (interpolate != NULL) {
inter = interpolate;
}
double weight = 0., dxy;
switch (inter) {
case cv::INTER_CUBIC:
if (dist_x >= 2.) {
return 0.;
} else if (dist_x > 1.) {
weight = 4. - 8. * dist_x + 5. * dist_x * dist_x - dist_x * dist_x * dist_x;
} else {
weight = 1. - 2 * dist_x * dist_x + dist_x * dist_x * dist_x;
}
if (dist_y >= 2.) {
return 0.;
} else if (dist_y > 1.) {
return weight * (4. - 8. * dist_y + 5. * dist_y * dist_y - dist_y * dist_y * dist_y);
} else {
return weight * (1. - 2 * dist_y * dist_y + dist_y * dist_y * dist_y);
}
case cv::INTER_LINEAR:
dxy = sqrt(dist_x * dist_x + dist_y * dist_y);
if (dxy < 1.) {
return (1. - dxy);
} else {
return 0.;
}
default:
return 0;
}
}