用OpenCV显示一幅图像到指定的窗体

本文详细介绍了如何基于OpenCV库的imshow源代码,自行编写了一个用于显示图像的函数。通过解析原始代码并进行适当修改,实现了一套简洁明了的图像展示解决方案。同时,文章还提供了将自定义函数应用于实际图像的例子,并讨论了与其他相关技术(如CxImage)的比较。

找了好久,没找到相应函数,于是参照cv::imshow的源代码,搞出来一份。
(OpenCV不简洁明了,学习的成本大于2天我就觉得太不值得了,下周准备试试CxImage)

#include "highgui.h"

#ifdef _DEBUG
     #pragma comment( lib, "opencv_core220d.lib" )
     #pragma comment( lib, "opencv_highgui220d.lib" )
#else
     #pragma comment( lib, "opencv_core220.lib" )
     #pragma comment( lib, "opencv_highgui220.lib" )
#endif

 

// 此代码是从OpenCV-2.2.0 中一点点扣出来的

bool MyShowImage( const cv::Mat& img, HDC hdc, const RECT& rect )

{

     CvMat _img = img;

     const CvArr* arr = &_img;

 

     CvMat stub;

     CvMat* image = cvGetMat( arr, &stub );

 

     // 构造BITMAPINFO头

     SIZE size = { image->width, image->height };

     int channels = 3;

     BITMAPINFO binfo;

     memset( &binfo, 0, sizeof(binfo));

     BITMAPINFOHEADER& bmih = binfo.bmiHeader;

     bmih.biSize = sizeof(BITMAPINFOHEADER);

     bmih.biWidth = size.cx;

     bmih.biHeight = abs(size.cy);

     bmih.biPlanes = 1;

     bmih.biBitCount = (unsigned short)(channels*8);

     bmih.biCompression = BI_RGB;

 

     void* dst_ptr = 0;

     HBITMAP hb = CreateDIBSection( hdc, &binfo, DIB_RGB_COLORS, &dst_ptr, 0, 0 );

 

     HDC windowdc = ::CreateCompatibleDC( hdc );

     SelectObject( windowdc, hb );

 

     CvMat dst;

     cvInitMatHeader( &dst, size.cy, size.cx, CV_8UC3, dst_ptr, (size.cx*channels + 3)&-4 );

 

     int origin = ((IplImage*)arr)->origin;

     cvConvertImage( image, &dst, origin==0 ? CV_CVTIMG_FLIP : 0 );

 

     // 显示

     SetStretchBltMode( hdc, COLORONCOLOR );

     //BitBlt( hdc, 0, 0, size.cx, size.cy, windowdc, 0, 0, SRCCOPY );

     StretchBlt( hdc, 0, 0, rect.right-rect.left, rect.bottom-rect.top, windowdc, 0, 0, size.cx, size.cy, SRCCOPY );

 

     return 0;

}

 

int main()

{

     const char* imagename = "1.tif";

 

     cv::Mat img = cv::imread( imagename );

     if( img.empty() || !img.data )

     {

        fprintf(stderr, "Can not load image %s\n", imagename);

        return -1;

     }

 

     //cv::namedWindow("image", CV_WINDOW_AUTOSIZE);

     //cv::imshow("image", img);

     //cv::waitKey();

 

     // 随便弄个窗体,然后显示上去

     HWND hwnd = ::GetConsoleWindow();

     RECT rect;

     GetWindowRect( hwnd, &rect );

     MyShowImage( img, ::GetWindowDC(hwnd), rect );

 

     return 0;

}




# http://www.antigrain.com/2011-02-23 19:47wetwoo

有时间看看这个:
http://www.antigrain.com/

### 使用 OpenCV 读取与显示图像的具体步骤及相关 API 函数 #### 步骤说明 使用 OpenCV 在 Python 中读取和显示图像的过程通常分为以下几个部分: 1. **导入必要的库**:首先需要导入 OpenCV 库,一般通过 `import cv2` 完成。 2. **读取图像**:利用 `cv2.imread()` 函数从本地路径加载图像文件到内存中。 3. **显示图像**:调用 `cv2.imshow()` 函数创建窗口并将图像数据显示出来。 4. **等待用户交互**:通过 `cv2.waitKey()` 设置程序暂停时间,以便观察图像。 5. **释放资源**:最后关闭所有由 OpenCV 打开的窗口以清理占用的系统资源。 --- #### 关键 API 函数及其功能 ##### 1. `cv2.imread(path, flags)` 该函数用于从指定路径加载一幅图像,并将其存储在一个 NumPy 数组中。参数如下: - `path`: 表示图像文件所在的绝对或相对路径字符串。 - `flags`: 控制读入模式的一个整数标志位,默认值为 `cv2.IMREAD_COLOR` (即彩色模式)[^1]。 返回值是一个三维 NumPy 数组(如果是彩色图像的话),其中每一行代表一列像素点的颜色信息[B,G,R]顺序排列[^2]。 ```python # 示例代码 image = cv2.imread('example.jpg', cv2.IMREAD_COLOR) # 彩色模式读取 gray_image = cv2.imread('example.jpg', cv2.IMREAD_GRAYSCALE) # 灰度模式读取 ``` ##### 2. `cv2.imshow(winname, mat)` 此方法用来在屏幕上绘制一个新窗口并填充给定的内容至该区域。它的两个必需参数分别是: - `winname`: 自定义名称赋予即将弹出的小窗体顶部标签栏文字串形式表达; - `mat`: 要展现出来的 ndarray 类型变量——也就是之前经 imread 方法获得的对象实例[^3]。 注意每次调用 imshow 后并不会立即刷新界面直到 waitKey 或 destroyAllWindows 命令被执行为止。 ```python # 示例代码 cv2.imshow('Color Image', image) cv2.imshow('Gray Scale Image', gray_image) ``` ##### 3. `cv2.waitKey(delay=None)` 这是一个无限循环阻塞当前线程直至键盘按键触发事件发生或者达到设定的最大延时毫秒数后自动退出的方法。如果没有设置延迟则会一直保持监听状态。典型应用场景是在查看静态图片的时候防止画面一闪而过无法看清细节情况[^1]。 常见写法有两种: - 如果希望按任意键继续运行后续脚本流程可传参零(`delay=0`) - 若要限定固定时间段比如一秒再往下走就填写对应正整数值如一千代表一秒单位ms. ```python # 示例代码 key = cv2.waitKey(0) & 0xFF # 捕获按下哪个键 if key == ord('q'): # 若检测到 'q' 键被点击,则结束进程 pass elif key == 27: # ESCAPE 键同样有效停止动作 exit() else: print("Pressed:", chr(key)) ``` ##### 4. `cv2.destroyAllWindows()` 销毁先前建立起来的所有活动窗口对象从而腾出更多可用空间供其他组件分配使用[^2]。建议放在整个应用程序终止前的位置确保不会遗留未清除干净的部分影响下次启动效率。 ```python # 示例代码 cv2.destroyAllWindows() ``` --- ### 整合示例代码 下面给出一段完整的例子演示如何结合以上提到的各种技术要点完成最基本的图像浏览任务。 ```python import cv2 # Step 1: Load an image from file system. original_image = cv2.imread('./sample_picture.png') # Check whether loading was successful or not before proceeding further actions. if original_image is None: raise ValueError("No valid input image found!") # Optional step to get some basic properties about loaded picture dimensions etc.. height, width, channels = original_image.shape[:3] print(f"Image Size -> Height:{height}, Width:{width}; Channels Count={channels}") # Step 2: Display the result on screen inside named window frame titled appropriately. cv2.namedWindow('Original Picture', cv2.WINDOW_AUTOSIZE) cv2.imshow('Original Picture', original_image) # Step 3: Wait indefinitely until user presses any button then close everything up neatly afterwards. pressed_key_code = cv2.waitKey(0) & 0xFF if pressed_key_code != 27 and pressed_key_code != ord('q'): print("User chose NOT TO EXIT via standard means...") # Cleanup phase regardless of how we got here eventually anyway... cv2.destroyAllWindows() ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值