日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

OpenCV 图像采样 插值 几何变换

發(fā)布時間:2023/11/27 生活经验 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 OpenCV 图像采样 插值 几何变换 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

轉自:http://hi.baidu.com/xiaoduo170/blog/item/6eefc612c9f8e9c6c2fd786f.html

?

InitLineIterator

初始化線段迭代器

int cvInitLineIterator( const CvArr* image, CvPoint pt1, CvPoint pt2, CvLineIterator* line_iterator, int connectivity=8 );
image
帶采線段的輸入圖像.
pt1
線段起始點
pt2
線段結束點
line_iterator
指向線段迭代器狀態(tài)結構的指針
connectivity
被掃描線段的連通數,4 或 8.

函數 cvInitLineIterator 初始化線段迭代器,并返回兩點之間的象素點數目。兩個點必須在圖像內。當迭代器初始化后,連接兩點的光柵線上所有點,都可以連續(xù)通過調用 CV_NEXT_LINE_POINT 來得到。線段上的點是使用 4-連通或8-連通利用 Bresenham 算法逐點計算的。

例子:使用線段迭代器計算彩色線上象素值的和

CvScalar sum_line_pixels( IplImage* image, CvPoint pt1, CvPoint pt2 ) 
{ CvLineIterator iterator; 
int blue_sum = 0, green_sum = 0, red_sum = 0;
 int count = cvInitLineIterator( image, pt1, pt2, &iterator, 8 );
 for( int i = 0; i < count; i++ )
{ blue_sum += iterator.ptr[0]; 
green_sum += iterator.ptr[1]; 
red_sum += iterator.ptr[2]; 
CV_NEXT_LINE_POINT(iterator); 
{ int offset, x, y; 
offset = iterator.ptr - (uchar*)(image->imageData); 
y = offset/image->widthStep; 
x = (offset - y*image->widthStep)/(3*sizeof(uchar) ); 
printf("(%d,%d)/n", x, y ); } 
} 
return cvScalar( blue_sum, green_sum, red_sum ); }

SampleLine

將圖像上某一光柵線上的像素數據讀入緩沖區(qū)

int cvSampleLine( const CvArr* image, CvPoint pt1, CvPoint pt2, void* buffer, int connectivity=8 );
image
輸入圖像
pt1
光柵線段的起點
pt2
光柵線段的終點
buffer
存儲線段點的緩存區(qū),必須有足夠大小來存儲點 max( |pt2.x-pt1.x|+1, |pt2.y-pt1.y|+1 ) :8-連通情況下,
或者 |pt2.x-pt1.x|+|pt2.y-pt1.y|+1 : 4-連通情況下.
connectivity
線段的連通方式, 4 or 8.

函數 cvSampleLine 實現了線段迭代器的一個特殊應用。它讀取由 pt1 和 pt2 兩點確定的線段上的所有圖像點,

包括終點,并存儲到緩存中。

?

GetRectSubPix

從圖像中提取象素矩形,使用子象素精度

void cvGetRectSubPix( const CvArr* src, CvArr* dst, CvPoint2D32f center );
src
輸入圖像.
dst
提取的矩形.
center
提取的象素矩形的中心,浮點數坐標。中心必須位于圖像內部.

函數 cvGetRectSubPix 從圖像 src 中提取矩形:

dst(x, y) = src(x + center.x - (width(dst)-1)*0.5, y + center.y - (height(dst)-1)*0.5)

其中非整數象素點坐標采用雙線性插值提取。對多通道圖像,每個通道獨立單獨完成提取。盡管函數要求矩形的中心一定要在輸入圖像之中,

但是有可能出現矩形的一部分超出圖像邊界的情況,這時,該函數復制邊界的模識(hunnish:即用于矩形相交的圖像邊界線段的象素來代替

矩形超越部分的象素)。

?

GetQuadrangleSubPix

提取象素四邊形,使用子象素精度

void cvGetQuadrangleSubPix( const CvArr* src, CvArr* dst, const CvMat* map_matrix );
src
輸入圖像.
dst
提取的四邊形.
map_matrix
3 × 2 變換矩陣 [A|b] (見討論).

函數 cvGetQuadrangleSubPix 以子象素精度從圖像 src 中提取四邊形,使用子象素精度,并且將結果存儲于 dst ,計算公式是:

dst(x + width(dst) / 2,y + height(dst) / 2) = src(A11x + A12y + b1,A21x + A22y + b2)

其中 A和 b 均來自映射矩陣(譯者注:A, b為幾何形變參數) ,映射矩陣為:

其中在非整數坐標 的象素點值通過雙線性變換得到。當函數需要圖像邊界外的像素點時,使用重復邊界

模式(replication border mode)恢復出所需的值。多通道圖像的每一個通道都單獨計算。

例子:使用 cvGetQuadrangleSubPix 進行圖像旋轉

#include "cv.h" 
#include "highgui.h" 
#include "math.h" 
int main( int argc, char** argv ) 
{ IplImage* src; 
if( argc==2 && (src = cvLoadImage(argv[1], -1))!=0) 
{ IplImage* dst = cvCloneImage( src ); 
int delta = 1; 
int angle = 0; 
cvNamedWindow( "src", 1 ); 
cvShowImage( "src", src ); 
for(;;) 
{ float m[6]; 
double factor = (cos(angle*CV_PI/180.) + 1.1)*3;
 CvMat M = cvMat( 2, 3, CV_32F, m ); 
int w = src->width; 
int h = src->height; 
m[0] = (float)(factor*cos(-angle*2*CV_PI/180.));
 m[1] = (float)(factor*sin(-angle*2*CV_PI/180.)); 
m[2] = w*0.5f; m[3] = -m[1]; m[4] = m[0]; m[5] = h*0.5f; 
cvGetQuadrangleSubPix( src, dst, &M, 1, cvScalarAll(0)); 
cvNamedWindow( "dst", 1 ); cvShowImage( "dst", dst ); 
if( cvWaitKey(5) == 27 ) break; angle = (angle + delta) % 360; } } return 0; }

Resize

圖像大小變換
void cvResize( const CvArr* src, CvArr* dst, int interpolation=CV_INTER_LINEAR );
src
輸入圖像.
dst
輸出圖像.
interpolation
插值方法:
  • CV_INTER_NN - 最近鄰插值,
  • CV_INTER_LINEAR - 雙線性插值 (缺省使用)
  • CV_INTER_AREA - 使用象素關系重采樣。當圖像縮小時候,該方法可以避免波紋出現。當圖像放大時,

類似于 CV_INTER_NN 方法..

  • CV_INTER_CUBIC - 立方插值.
函數 cvResize 將圖像 src 改變尺寸得到與 dst 同樣大小。若設定 ROI,函數將按常規(guī)支持 ROI.

WarpAffine

對圖像做仿射變換
void cvWarpAffine( const CvArr* src, CvArr* dst, const CvMat* map_matrix, 
                                  int flags=CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS, CvScalar fillval=cvScalarAll(0) );
src
輸入圖像.
dst
輸出圖像.
map_matrix
2×3 變換矩陣
flags
插值方法和以下開關選項的組合:
  • CV_WARP_FILL_OUTLIERS - 填充所有輸出圖像的象素。如果部分象素落在輸入圖像的邊界外,

那么它們的值設定為 fillval.

  • CV_WARP_INVERSE_MAP - 指定 map_matrix 是輸出圖像到輸入圖像的反變換,因此可以直接用來做象素插值。
否則, 函數從 map_matrix 得到反變換。
fillval
用來填充邊界外面的值
函數 cvWarpAffine 利用下面指定的矩陣變換輸入圖像: 
  • 如果沒有指定 CV_WARP_INVERSE_MAP , ,
  • 否則,
函數與 cvGetQuadrangleSubPix 類似,但是不完全相同。 cvWarpAffine 要求輸入和輸出圖像具有同樣的數據類型,
有更大的資源開銷(因此對小圖像不太合適)而且輸出圖像的部分可以保留不變。而 cvGetQuadrangleSubPix 可以精確地從8位
圖像中提取四邊形到浮點數緩存區(qū)中,具有比較小的系統開銷,而且總是全部改變輸出圖像的內容。
要變換稀疏矩陣,使用 cxcore 中的函數 cvTransform 。

GetAffineTransform

由三對點計算仿射變換
CvMat* cvGetAffineTransform( const CvPoint2D32f* src, const CvPoint2D32f* dst, CvMat* map_matrix );
src
輸入圖像的三角形頂點坐標。
dst
輸出圖像的相應的三角形頂點坐標。
map_matrix
指向2×3輸出矩陣的指針。
函數cvGetAffineTransform計算滿足以下關系的仿射變換矩陣:

這里,dst(i) = (x'i,y'i),src(i) = (xi,yi),i = 0..2.

2DRotationMatrix

計算二維旋轉的仿射變換矩陣
CvMat* cv2DRotationMatrix( CvPoint2D32f center, double angle, double scale, CvMat* map_matrix );
center
輸入圖像的旋轉中心坐標
angle
旋轉角度(度)。正值表示逆時針旋轉(坐標原點假設在左上角).
scale
各項同性的尺度因子
map_matrix
輸出 2×3 矩陣的指針
函數 cv2DRotationMatrix 計算矩陣:
[ α β | (1-α)*center.x - β*center.y ] [ -β α | β*center.x + (1-α)*center.y ] where α=scale*cos(angle), 
β=scale*sin(angle)
該變換并不改變原始旋轉中心點的坐標,如果這不是操作目的,則可以通過調整平移量改變其坐標(譯者注:通過簡單的推導可知,
仿射變換的實現是首先將旋轉中心置為坐標原點,再進行旋轉和尺度變換,最后重新將坐標原點設定為輸入圖像的左上角,
這里的平移量是center.x, center.y).

WarpPerspective

對圖像進行透視變換
void cvWarpPerspective( const CvArr* src, CvArr* dst, const CvMat* map_matrix, 
                                          int flags=CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS, CvScalar fillval=cvScalarAll(0) );
src
輸入圖像.
dst
輸出圖像.
map_matrix
3×3 變換矩陣
flags
插值方法和以下開關選項的組合:
  • CV_WARP_FILL_OUTLIERS - 填充所有縮小圖像的象素。如果部分象素落在輸入圖像的邊界外,那么它們的值設定為 fillval.
  • CV_WARP_INVERSE_MAP - 指定 matrix 是輸出圖像到輸入圖像的反變換,因此可以直接用來做象素插值。否則,
函數從 map_matrix 得到反變換。
fillval
用來填充邊界外面的值
函數 cvWarpPerspective 利用下面指定矩陣變換輸入圖像: 
  • 如果沒有指定 CV_WARP_INVERSE_MAP , ,
  • 否則,
要變換稀疏矩陣,使用 cxcore 中的函數 cvTransform 。

WarpPerspectiveQMatrix

用4個對應點計算透視變換矩陣
CvMat* cvWarpPerspectiveQMatrix( const CvPoint2D32f* src, const CvPoint2D32f* dst, CvMat* map_matrix );
src
輸入圖像的四邊形的4個點坐標
dst
輸出圖像的對應四邊形的4個點坐標
map_matrix
輸出的 3×3 矩陣
函數 cvWarpPerspectiveQMatrix 計算透視變換矩陣,使得:
(tix'i,tiy'i,ti)T=matrix?(xi,yi,1)T
其中 dst(i)=(x'i,y'i), src(i)=(xi,yi), i=0..3.

GetPerspectiveTransform

由四對點計算透射變換
CvMat* cvGetPerspectiveTransform( const CvPoint2D32f* src, const CvPoint2D32f* dst, CvMat* map_matrix ); 
#define cvWarpPerspectiveQMatrix cvGetPerspectiveTransform
src
輸入圖像的四邊形頂點坐標。
dst
輸出圖像的相應的四邊形頂點坐標。
map_matrix
指向3×3輸出矩陣的指針。
函數cvGetPerspectiveTransform計算滿足以下關系的透射變換矩陣:
這里,dst(i) = (x'i,y'i),src(i) = (xi,yi),i = 0..3.

Remap

對圖像進行普通幾何變換

void cvRemap( const CvArr* src, CvArr* dst, const CvArr* mapx, const CvArr* mapy,
                                  int flags=CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS, CvScalar fillval=cvScalarAll(0) );
src
輸入圖像.
dst
輸出圖像.
mapx
x坐標的映射 (32fC1 image).
mapy
y坐標的映射 (32fC1 image).
flags
插值方法和以下開關選項的組合:
  • CV_WARP_FILL_OUTLIERS - 填充邊界外的像素. 如果輸出圖像的部分象素落在變換后的邊界外,那么它們的值設定為 fillval。
fillval
用來填充邊界外面的值.

函數 cvRemap 利用下面指定的矩陣變換輸入圖像:

dst(x,y)<-src(mapx(x,y),mapy(x,y))

與其它幾何變換類似,可以使用一些插值方法(由用戶指定,譯者注:同cvResize)來計算非整數坐標的像素值。

?

LogPolar

把圖像映射到極指數空間

void cvLogPolar( const CvArr* src, CvArr* dst, CvPoint2D32f center, double M, 
                                         int flags=CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS );
src
輸入圖像。
dst
輸出圖像。
center
變換的中心,輸出圖像在這里最精確。
M
幅度的尺度參數,見下面公式。
flags
插值方法和以下選擇標志的結合
  • CV_WARP_FILL_OUTLIERS -填充輸出圖像所有像素,如果這些點有和外點對應的,則置零。
  • CV_WARP_INVERSE_MAP - 表示矩陣由輸出圖像到輸入圖像的逆變換,并且因此可以直接用于像素插值。否則,
函數從map_matrix中尋找逆變換。
fillval
用于填充外點的值。

函數cvLogPolar用以下變換變換輸入圖像:

正變換 (CV_WARP_INVERSE_MAP 未置位):

dst(phi,rho)<-src(x,y)

逆變換 (CV_WARP_INVERSE_MAP 置位):

dst(x,y)<-src(phi,rho),

這里,

rho=M*log(sqrt(x2+y2)) phi=atan(y/x)

此函數模仿人類視網膜中央凹視力,并且對于目標跟蹤等可用于快速尺度和旋轉變換不變模板匹配。

Example. Log-polar transformation.

#include <cv.h> 
#include <highgui.h> 
int main(int argc, char** argv) 
{ IplImage* src; 
if( argc == 2 && (src=cvLoadImage(argv[1],1) != 0 ) 
{ IplImage* dst = cvCreateImage( cvSize(256,256), 8, 3 );
 IplImage* src2 = cvCreateImage( cvGetSize(src), 8, 3 ); 
cvLogPolar( src, dst, cvPoint2D32f(src->width/2,src->height/2), 40, CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS ); 
cvLogPolar( dst, src2, cvPoint2D32f(src->width/2,src->height/2), 40, CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS+
CV_WARP_INVERSE_MAP ); 
cvNamedWindow( "log-polar", 1 ); cvShowImage( "log-polar", dst ); 
cvNamedWindow( "inverse log-polar", 1 ); cvShowImage( "inverse log-polar", src2 );
cvWaitKey(); } return 0; }

總結

以上是生活随笔為你收集整理的OpenCV 图像采样 插值 几何变换的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

歡迎分享!

轉載請說明來源于"生活随笔",并保留原作者的名字。

本文地址:OpenCV 图像采样 插值 几何变换