数字图像处理 - NetVips图像处理库的初探

        libvips图像处理库运行速度快,并且占用的内存很少。 libvips是根据LGPL 2.1+授权的。(https://github.com/libvips/libvips)它具有约300种运算,涵盖算术,直方图,卷积,形态运算,频率滤波,颜色,重采样,统计等。虽然相比opencv等专业的库差了一些,但是其不占内存的特点,使其适合处理较大的图片。

        NetVips 是libvips的.net封装,NetVips速度快,几乎不需要内存。 NetVips.Benchmarks项目针对Magick.NET和ImageSharp测试NetVips。 NetVips比Magick.NET快14倍,比ImageSharp快5倍。(https://kleisauke.github.io/net-vips/

        在windows项目使用还是比较方便的。nuget搜索NetVips,安装下面3个包即可。NetVips / NetVips.Native.win-x64 / NetVips.Native.win-x86

       一、占用内存分析

        看libvips的源码内,对于内存的处理部分,在mapfile.c中,有创建mmap,所以分析占用内存较少,但是在使用的时候会写入硬盘。

void *
vips__mmap( int fd, int writeable, size_t length, gint64 offset )
{
	void *baseaddr;

#ifdef DEBUG
	printf( "vips__mmap: length = 0x%zx, offset = 0x%lx\n", 
		length, offset );
#endif /*DEBUG*/

#ifdef OS_WIN32
{
	HANDLE hFile = (HANDLE) _get_osfhandle( fd );

	DWORD flProtect;
	DWORD dwDesiredAccess;

        HANDLE hMMFile;

	ULARGE_INTEGER quad;
	DWORD dwFileOffsetHigh;
	DWORD dwFileOffsetLow;

	if( writeable ) {
		flProtect = PAGE_READWRITE;
		dwDesiredAccess = FILE_MAP_WRITE;
	}
	else {
		flProtect = PAGE_READONLY;
		dwDesiredAccess = FILE_MAP_READ;
	}

	quad.QuadPart = offset;
	dwFileOffsetLow = quad.LowPart;
	dwFileOffsetHigh = quad.HighPart;

        if( !(hMMFile = CreateFileMapping( hFile,
		NULL, flProtect, 0, 0, NULL )) ) {
                vips_error_system( GetLastError(), "vips_mapfile", 
			"%s", _( "unable to CreateFileMapping" ) );
		printf( "CreateFileMapping failed: %s\n", vips_error_buffer() );
                return( NULL );
        }

        if( !(baseaddr = (char *)MapViewOfFile( hMMFile, dwDesiredAccess, 
		dwFileOffsetHigh, dwFileOffsetLow, length )) ) {
                vips_error_system( GetLastError(), "vips_mapfile",
			"%s", _( "unable to MapViewOfFile" ) );
		printf( "MapViewOfFile failed: %s\n", vips_error_buffer() );
		CloseHandle( hMMFile );
                return( NULL );
        }

	/* Can close mapping now ... view stays until UnmapViewOfFile().

		FIXME ... is this a performance problem?

	 */
	CloseHandle( hMMFile );
}
#else /*!OS_WIN32*/
{
	int prot;
	int flags;

	if( writeable ) 
		prot = PROT_WRITE;
	else 
		prot = PROT_READ;

	flags = MAP_SHARED;

	/* OS X caches mmapped files very aggressively if this flags is not
	 * set. Scanning a large file without this flag will cause every other
	 * process to get swapped out and kill performance.
	 */
#ifdef MAP_NOCACHE
	flags |= MAP_NOCACHE;
#endif /*MAP_NOCACHE*/

	/* Casting gint64 to off_t should be safe, even on *nixes without
	 * LARGEFILE.
	 */

	baseaddr = mmap( 0, length, prot, flags, fd, (off_t) offset );
	if( baseaddr == MAP_FAILED ) { 
		vips_error_system( errno, "vips_mapfile", 
			"%s", _( "unable to mmap" ) );
		g_warning( _( "map failed (%s), "
			"running very low on system resources, "
			"expect a crash soon" ), strerror( errno ) );
		return( NULL ); 
	}
}
#endif /*OS_WIN32*/

	return( baseaddr );
}

      二、简单使用

        通道分割

NetVips.Image image = NetVips.Image.NewFromFile("C:\\Users\\xiaomao\\Desktop\\1.jpg", memory: false, access: Enums.Access.Random);
NetVips.Image[] images = image.Bandsplit();

        水平镜像

NetVips.Image image = NetVips.Image.NewFromFile("C:\\Users\\xiaomao\\Desktop\\1.jpg", memory: false, access: Enums.Access.Random);
NetVips.Image gauss = image.Flip(NetVips.Enums.Direction.Horizontal);

         高斯滤波

NetVips.Image image = NetVips.Image.NewFromFile("C:\\Users\\xiaomao\\Desktop\\1.jpg", memory: false, access: Enums.Access.Random);
NetVips.Image gauss = image.Gaussblur(15);

        图像旋转

NetVips.Image image = NetVips.Image.NewFromFile("C:\\Users\\xiaomao\\Desktop\\2.jpg", memory: false, access: Enums.Access.Random);
NetVips.Image gauss = image.Rot90();

        Canny/Sobel边缘检测

NetVips.Image image = NetVips.Image.NewFromFile("C:\\Users\\xiaomao\\Desktop\\1.jpg", memory: false, access: Enums.Access.Random);
NetVips.Image canny= image.Canny(1.8, Enums.Precision.Float);
NetVips.Image sobel = image.Sobel();

猜你喜欢

转载自blog.csdn.net/bashendixie5/article/details/114155983