cuda npp库旋转图片
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <assert.h> 5 #include <math.h> 6 #include <windows.h> 7 #include <FreeImage.h> 8 #include <cuda_runtime.h> 9 #include <npp.h> 10 11 12 #pragma comment(lib, "FreeImage.lib") 13 #pragma comment(lib, "cudart.lib") 14 #pragma comment(lib, "nppi.lib") 15 16 17 FIBITMAP* LoadImg( const char* szFile ) 18 { 19 FREE_IMAGE_FORMAT nFif; 20 21 if ( szFile == NULL || *szFile == 0 ) 22 { 23 return NULL; 24 } 25 26 if ( ( nFif = FreeImage_GetFileType( szFile, 0 ) ) == FIF_UNKNOWN ) 27 { 28 if ( ( nFif = FreeImage_GetFIFFromFilename( szFile ) ) == FIF_UNKNOWN ) 29 { 30 return NULL; 31 } 32 } 33 34 if ( !FreeImage_FIFSupportsReading( nFif ) ) 35 { 36 return NULL; 37 } 38 39 return FreeImage_Load( nFif, szFile ); 40 } 41 42 43 int main( int argc, char* argv[] ) 44 { 45 cudaError_t cuRet; 46 NppStatus nppRet; 47 BOOL fiRet; 48 FIBITMAP* pSrcBmp; 49 FIBITMAP* pDstBmp; 50 unsigned char* pSrcData; 51 unsigned char* pDstData; 52 Npp8u* pSrcDataCUDA; 53 Npp8u* pDstDataCUDA; 54 NppiSize oSrcSize; 55 NppiSize oDstSize; 56 NppiRect oSrcROI; 57 NppiRect oDstROI; 58 int nImgBpp; 59 int nSrcPitch; 60 int nDstPitch; 61 int nSrcPitchCUDA; 62 int nDstPitchCUDA; 63 double aBoundingBox[2][2]; 64 double nAngle; 65 66 if ( argc < 3 ) 67 { 68 return -1; 69 } 70 71 /* 载入文件 */ 72 pSrcBmp = LoadImg( argv[1] ); 73 assert( pSrcBmp != NULL ); 74 75 nImgBpp = ( FreeImage_GetBPP( pSrcBmp ) >> 3 ); 76 pSrcData = FreeImage_GetBits( pSrcBmp ); 77 78 oSrcSize.width = ( int )FreeImage_GetWidth( pSrcBmp ); 79 oSrcSize.height = ( int )FreeImage_GetHeight( pSrcBmp ); 80 nSrcPitch = ( int )FreeImage_GetPitch( pSrcBmp ); 81 82 oSrcROI.x = oSrcROI.y = 0; 83 oSrcROI.width = oSrcSize.width; 84 oSrcROI.height = oSrcSize.height; 85 86 nAngle = atof( argv[2] ); 87 88 /* 设置显卡,构建上下文 */ 89 cuRet = cudaSetDevice( 0 ); 90 assert( cuRet == cudaSuccess ); 91 92 /* 分配显存 */ 93 switch ( nImgBpp ) 94 { 95 case 1: 96 pSrcDataCUDA = nppiMalloc_8u_C1( oSrcSize.width, oSrcSize.height, &nSrcPitchCUDA ); 97 break; 98 case 3: 99 pSrcDataCUDA = nppiMalloc_8u_C3( oSrcSize.width, oSrcSize.height, &nSrcPitchCUDA ); 100 break; 101 case 4: 102 pSrcDataCUDA = nppiMalloc_8u_C4( oSrcSize.width, oSrcSize.height, &nSrcPitchCUDA ); 103 break; 104 default: 105 assert( 0 ); 106 break; 107 } 108 assert( pSrcDataCUDA != NULL ); 109 110 /* 将原图传入显存 */ 111 cudaMemcpy2D( pSrcDataCUDA, nSrcPitchCUDA, pSrcData, nSrcPitch, oSrcSize.width * nImgBpp, oSrcSize.height, cudaMemcpyHostToDevice ); 112 113 /* 计算旋转后长宽 */ 114 nppiGetRotateBound( oSrcROI, aBoundingBox, nAngle, 0, 0 ); 115 oDstSize.width = ( int )ceil( fabs( aBoundingBox[1][0] - aBoundingBox[0][0] ) ); 116 oDstSize.height = ( int )ceil( fabs( aBoundingBox[1][1] - aBoundingBox[0][1] ) ); 117 118 /* 建目标图 */ 119 pDstBmp = FreeImage_Allocate( oDstSize.width, oDstSize.height, nImgBpp << 3 ); 120 assert( pDstBmp != NULL ); 121 122 pDstData = FreeImage_GetBits( pDstBmp ); 123 124 nDstPitch = ( int )FreeImage_GetPitch( pDstBmp ); 125 oDstROI.x = oDstROI.y = 0; 126 oDstROI.width = oDstSize.width; 127 oDstROI.height = oDstSize.height; 128 129 /* 分配显存 */ 130 switch ( nImgBpp ) 131 { 132 case 1: 133 pDstDataCUDA = nppiMalloc_8u_C1( oDstSize.width, oDstSize.height, &nDstPitchCUDA ); 134 break; 135 case 3: 136 pDstDataCUDA = nppiMalloc_8u_C3( oDstSize.width, oDstSize.height, &nDstPitchCUDA ); 137 break; 138 case 4: 139 pDstDataCUDA = nppiMalloc_8u_C4( oDstSize.width, oDstSize.height, &nDstPitchCUDA ); 140 break; 141 } 142 assert( pDstDataCUDA != NULL ); 143 cudaMemset2D( pDstDataCUDA, nDstPitchCUDA, 0, oDstSize.width * nImgBpp, oDstSize.height ); 144 145 /* 处理 */ 146 switch ( nImgBpp ) 147 { 148 case 1: 149 nppRet = nppiRotate_8u_C1R( pSrcDataCUDA, oSrcSize, nSrcPitchCUDA, oSrcROI, 150 pDstDataCUDA, nDstPitchCUDA, oDstROI, 151 nAngle, - aBoundingBox[0][0], - aBoundingBox[0][1], NPPI_INTER_CUBIC ); 152 break; 153 case 3: 154 nppRet = nppiRotate_8u_C3R( pSrcDataCUDA, oSrcSize, nSrcPitchCUDA, oSrcROI, 155 pDstDataCUDA, nDstPitchCUDA, oDstROI, 156 nAngle, - aBoundingBox[0][0], - aBoundingBox[0][1], NPPI_INTER_CUBIC ); 157 break; 158 case 4: 159 nppRet = nppiRotate_8u_C4R( pSrcDataCUDA, oSrcSize, nSrcPitchCUDA, oSrcROI, 160 pDstDataCUDA, nDstPitchCUDA, oDstROI, 161 nAngle, - aBoundingBox[0][0], - aBoundingBox[0][1], NPPI_INTER_CUBIC ); 162 break; 163 } 164 assert( nppRet == NPP_NO_ERROR ); 165 166 cudaMemcpy2D( pDstData, nDstPitch, pDstDataCUDA, nDstPitchCUDA, oDstSize.width * nImgBpp, oDstSize.height, cudaMemcpyDeviceToHost ); 167 168 fiRet = FreeImage_Save( FIF_BMP, pDstBmp, "ret.bmp" ); 169 assert( fiRet ); 170 171 nppiFree( pSrcDataCUDA ); 172 nppiFree( pDstDataCUDA ); 173 174 cudaDeviceReset(); 175 176 FreeImage_Unload( pSrcBmp ); 177 FreeImage_Unload( pDstBmp ); 178 179 return 0; 180 }
下面是所有通道的,扩展了一点。以后自己用
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <assert.h> 5 #include <math.h> 6 #include <windows.h> 7 8 #include <FreeImage.h> 9 10 #include <cuda_runtime.h> 11 #include <npp.h> 12 13 14 int main( int argc, char* argv[] ) 15 { 16 cudaError_t cuRet; 17 NppStatus nppRet; 18 BOOL fiRet; 19 FIBITMAP* pSrcBmp; 20 FIBITMAP* pDstBmp; 21 unsigned char* pSrcData; 22 unsigned char* pDstData; 23 Npp8u* pSrcDataCUDA; 24 Npp8u* pDstDataCUDA; 25 NppiSize oSrcSize; 26 NppiSize oDstSize; 27 NppiRect oSrcROI; 28 NppiRect oDstROI; 29 int nSrcPitch; 30 int nDstPitch; 31 int nSrcPitchCUDA; 32 int nDstPitchCUDA; 33 double aBoundingBox[2][2]; 34 double nAngle; 35 36 37 /* 设置显卡,构建上下文 */ 38 cuRet = cudaSetDevice( 0 ); 39 assert( cuRet == cudaSuccess ); 40 41 /* 打开文件 */ 42 pSrcBmp = FreeImage_Load( FIF_BMP, "1.bmp" ); 43 assert( pSrcBmp != NULL ); 44 45 pSrcData = FreeImage_GetBits( pSrcBmp ); 46 assert( pSrcData != NULL ); 47 48 oSrcSize.width = ( int )FreeImage_GetWidth( pSrcBmp ); 49 oSrcSize.height = ( int )FreeImage_GetHeight( pSrcBmp ); 50 nSrcPitch = ( int )FreeImage_GetPitch( pSrcBmp ); 51 52 oSrcROI.x = oSrcROI.y = 0; 53 oSrcROI.width = oSrcSize.width; 54 oSrcROI.height = oSrcSize.height; 55 56 nAngle = 45; 57 58 59 /* 分配显存 */ 60 pSrcDataCUDA = nppiMalloc_8u_C1( oSrcSize.width, oSrcSize.height, &nSrcPitchCUDA ); 61 assert( pSrcDataCUDA != NULL ); 62 63 64 /* 计算旋转后长宽 */ 65 nppiGetRotateBound( oSrcROI, aBoundingBox, nAngle, 0, 0 ); 66 oDstSize.width = ( int )ceil( fabs( aBoundingBox[1][0] - aBoundingBox[0][0] ) ); 67 oDstSize.height = ( int )ceil( fabs( aBoundingBox[1][1] - aBoundingBox[0][1] ) ); 68 69 /* 建目标图 */ 70 pDstBmp = FreeImage_Allocate( oDstSize.width, oDstSize.height, 8 ); 71 assert( pDstBmp != NULL ); 72 73 pDstData = FreeImage_GetBits( pDstBmp ); 74 75 nDstPitch = ( int )FreeImage_GetPitch( pDstBmp ); 76 oDstROI.x = oDstROI.y = 0; 77 oDstROI.width = oDstSize.width; 78 oDstROI.height = oDstSize.height; 79 80 /* 分配显存 */ 81 pDstDataCUDA = nppiMalloc_8u_C1( oDstSize.width, oDstSize.height, &nDstPitchCUDA ); 82 assert( pDstDataCUDA != NULL ); 83 84 cudaMemcpy2D( pSrcDataCUDA, nSrcPitchCUDA, pSrcData, nSrcPitch, oSrcSize.width, oSrcSize.height, cudaMemcpyHostToDevice ); 85 cudaMemset2D( pDstDataCUDA, nDstPitchCUDA, 0, oDstSize.width, oDstSize.height ); 86 87 /* 处理 */ 88 nppRet = nppiRotate_8u_C1R( pSrcDataCUDA, oSrcSize, nSrcPitchCUDA, oSrcROI, 89 pDstDataCUDA, nDstPitchCUDA, oDstROI, 90 nAngle, - aBoundingBox[0][0], - aBoundingBox[0][1], NPPI_INTER_CUBIC ); 91 assert( nppRet == NPP_NO_ERROR ); 92 93 cudaMemcpy2D( pDstData, nDstPitch, pDstDataCUDA, nDstPitchCUDA, oDstSize.width, oDstSize.height, cudaMemcpyDeviceToHost ); 94 95 fiRet = FreeImage_Save( FIF_BMP, pDstBmp, "2.bmp" ); 96 assert( fiRet ); 97 98 nppiFree( pSrcDataCUDA ); 99 nppiFree( pDstDataCUDA ); 100 101 cudaDeviceReset(); 102 103 FreeImage_Unload( pSrcBmp ); 104 FreeImage_Unload( pDstBmp ); 105 106 return 0; 107 }