??低曆芯吭篒mageNet2016競賽經驗分享
深度學習之圖像的數據增強
data augmentation 數據增強方法總結
圖片的數據增強(Data Augmentation)方法
opencv 圖像仿射變換 計算仿射變換后對應特征點的新坐標 圖像旋轉、縮放、平移
在訓練機器學習或深度學習模型時,我們通常需要輸入充足的數據量.若數據量比較小,可以對原有的圖像數據進行幾何變換,改變圖像像素的位置并保證特征不變。上面列出的參考資料中已經列出了很多數據增強的方法,這里主要對圖像旋轉進行介紹。
首先介紹圖像旋轉及opencv中的函數:getRotationMartrix2D及warpAffine函數,其中getRotationMartrix2D用于獲取旋轉矩陣,warpAffine用于旋轉。其中warpAffine函數中的仿射變換矩陣除了getRotationMartrix2D外,還可以通過getAffineform獲得:warp_mat =?getAffineform(srcTri, dstTri),dstTri為旋轉后的圖像坐標,坐標應該與原圖像的坐標順序相對應。左下角為起點,按照順時針旋轉。
- 旋轉一幅圖像需要三個參數:1.旋轉圖像所要圍繞的中心;2.旋轉角度(opencv中正角度是逆時針的);3.可選擇:縮放因子
1 Mat ImageRotate(Mat src,
const Point _center,
double angle)
2 {
3 Point2f center;
4 center.x =
float(_center.x);
5 center.y =
float(_center.y);
6
7 //計算二維旋轉的仿射變換矩陣
8 Mat rot_mat = getRotationMatrix2D(center, angle,
1);
9
10 // rotate
11 Mat dst;
12 warpAffine(src, dst, rot_mat, Size(src.cols, src.rows), CV_INTER_LINEAR);
13 return dst;
14 }
- 假設已經有一個原圖像中的特征點的坐標 Point2f point; ?那么計算這個point的對應的仿射變換之后在新的圖像中的坐標位置,使用的方法如下函數:
1 Point getPointAffinedPos(
const Point src,
const Point center,
double angle)
2 {
3 Point dst;
4 int x = src.x -
center.x;
5 int y = src.y -
center.y;
6
7 dst.x = cvRound(x * cos(angle) + y * sin(angle) +
center.x);
8 dst.y = cvRound(-x * sin(angle) + y * cos(angle) +
center.y);
9 return dst;
10 }
要特別注意的是,在對一個原圖像中的像素的坐標進行計算仿射變換之后的坐標的時候,一定要按照仿射變換的基本原理,將原來的坐標減去仿射變換的旋轉中心的坐標,這樣仿射變換之后得到的坐標再加上仿射變換旋轉中心坐標才是原坐標在新的仿射變換之后的圖像中的正確坐標。
1 Point Leye;
2 Leye.x =
265;
3 Leye.y =
265;
4 CvPoint Reye;
5 Reye.x =
328;
6 Reye.y =
265;
7
8 // draw pupil
9 src.at<unsigned
char>(Leye.y, Leye.x) =
255;
10 src.at<unsigned
char>(Reye.y, Reye.x) =
255;
11
12 imshow(
"src", src);
13
14 //
15 Point center;
16 center.x = img.cols /
2;
17 center.y = img.rows /
2;
18 //L表示long double,主要用于在某些支持擴展精度的機器上擴展精度
19 double angle =
15L;
20
21 Mat dst =
ImageRotate(img, center, angle);
22
23 // 計算原特征點在旋轉后圖像中的對應的坐標
24 Point l2 = getPointAffinedPos(Leye, center, angle * CV_PI /
180);
25 Point r2 = getPointAffinedPos(Reye, center, angle * CV_PI /
180);
26
27 // draw pupil
28 dst.at<unsigned
char>(l2.y, l2.x) =
255;
29 dst.at<unsigned
char>(r2.y, r2.x) =
255;
上述代碼是先對一幅圖片標注兩個點,然后對圖像進行旋轉,并找到旋轉后標注點的對應坐標。
? ? ? ??
如果是擴充GT,可以通過少量標注的GT進行圖像的旋轉來獲取更多的數據,這里涉及到的樣本是將GT中的目標摳出來,然后多次旋轉圖像,再摳取目標,達到擴充GT的目的。博主這里的標注是目標四個角的坐標,先將目標用boundingRect框出,再將矩形擴展為正方形,最后提取對應目標。
1 void optimize(Rect& src_temp, Mat src,
int&
flag)
2 {
3 if (src_temp.height >=
src_temp.width)
4 {
5 float delta = src_temp.height -
src_temp.width;
6 src_temp.x = src_temp.x - delta /
2.0;
7 src_temp.width =
src_temp.height;
8 }
9 else
10 {
11 float delta = src_temp.width -
src_temp.height;
12 src_temp.y = src_temp.y - delta /
2.0;
13 src_temp.height =
src_temp.width;
14 }
15 if (src_temp.x >=
0 && src_temp.y >=
0 && src_temp.x + src_temp.width <= src.cols &&
16 src_temp.y + src_temp.height <=
src.rows)
17 flag =
1;
18 else
19 flag =
0;
20 }
1 for (
int j =
0; j < objectGT.size(); j++
)
2 {
3 vector<Point2f>
contours;
4 Point2f p[
4];
5 p[
0].x =
objectGT[j].x0;
6 p[
0].y =
objectGT[j].y0;
7 contours.push_back(p[
0]);
8
9 p[
1].x =
objectGT[j].x1 ;
10 p[
1].y =
objectGT[j].y1 ;
11 contours.push_back(p[
1]);
12
13 p[
2].x =
objectGT[j].x2 ;
14 p[
2].y =
objectGT[j].y2 ;
15 contours.push_back(p[
2]);
16
17 p[
3].x =
objectGT[j].x3 ;
18 p[
3].y =
objectGT[j].y3 ;
19 contours.push_back(p[
3]);
20 Rect src_temp =
boundingRect(contours);
21 int flag =
0;
22 optimize(src_temp, src, flag);
23 Mat src_out;
24 if (flag ==
1)
25 src_out =
src(src_temp);
26 if (flag ==
0)
27 continue;
28 }
1 p[
0] = getPointAffinedPos(p[
0], center, angle * CV_PI /
180);
2 contours.push_back(p[
0]);
3 p[
1] = getPointAffinedPos(p[
1], center, angle * CV_PI /
180);
4 contours.push_back(p[
1]);
5 p[
2] = getPointAffinedPos(p[
2], center, angle * CV_PI /
180);
6 contours.push_back(p[
2]);
7 p[
3] = getPointAffinedPos(p[
3], center, angle * CV_PI /
180);
8 contours.push_back(p[
3]);10 //-------------------
11 Rect src_temp =
boundingRect(contours);
12 int flag =
0;
13 optimize(src_temp, src, flag);
14 Mat src_out;
15 if (flag ==
1)
16 src_out =
src(src_temp);
17 if (flag ==
0)
18 continue;
?
?
轉載于:https://www.cnblogs.com/qinguoyi/p/8359245.html
總結
以上是生活随笔為你收集整理的数据增强之图像旋转及坐标对应(附代码)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。