OpenCV_提取图片中任意形状的区域

转载自:http://blog.csdn.net/hanbinga17/article/details/6536331#

----------------------------------------------------------------------------------------------------------------------------------------------

正在做一个基于内容的图像检索项目,客户要求可以让用户提取图片上的任意形状的子图作为输入。为了实现这个功能,花了不少精力,中间绕了不少圈子。现在问题总算解决了,把主要的思路记录一下,希望能帮到有同样需求的朋友。

由于这个项目使用了第三方的开源图像库opencv,所以这个功能也是借助opencv来实现的。

首先需要解决的是在图片中绘制曲线的问题,思路很简单,只需要响应鼠标事件通过描点、连线的方式就可以完成。在opencv中需要使用回调来响应鼠标事件,opencv中文站上有很好的示例,关键代码:

[c-sharp:nogutter] view plaincopy

  1. #include "cv.h"
  2. #include "highgui.h"
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. IplImage* inpaint_mask = 0;
  6. IplImage* img0 = 0, *img = 0, *inpainted = 0;
  7. CvPoint prev_pt = {-1,-1};
  8. void on_mouse( int event, int x, int y, int flags, void* zhang)
  9. {
  10. if( !img )
  11. return;
  12. if( event == CV_EVENT_LBUTTONUP || !(flags & CV_EVENT_FLAG_LBUTTON) )
  13. prev_pt = cvPoint(-1,-1);
  14. else if( event == CV_EVENT_LBUTTONDOWN )
  15. prev_pt = cvPoint(x,y);
  16. else if( event == CV_EVENT_MOUSEMOVE && (flags & CV_EVENT_FLAG_LBUTTON) )
  17. {
  18. CvPoint pt = cvPoint(x,y);
  19. if( prev_pt.x < 0 )
  20. prev_pt = pt;
  21. cvLine( inpaint_mask, prev_pt, pt, cvScalarAll(255), 5, 8, 0 );
  22. cvLine( img, prev_pt, pt, cvScalarAll(255), 5, 8, 0 );
  23. prev_pt = pt;
  24. cvShowImage( "image", img );
  25. }
  26. }
  27. int main( int argc, char** argv )
  28. {
  29. char* filename = argc >= 2 ? argv[1] : (char*)"fruits.jpg";
  30. if( (img0 = cvLoadImage(filename,-1)) == 0 )
  31. return 0;
  32. printf( "Hot keys: /n"
  33. cvNamedWindow( "image", 1 );
  34. img = cvCloneImage( img0 );
  35. inpainted = cvCloneImage( img0 );
  36. inpaint_mask = cvCreateImage( cvGetSize(img), 8, 1 );
  37. cvZero( inpaint_mask );
  38. cvZero( inpainted );
  39. cvShowImage( "image", img );
  40. cvShowImage( "watershed transform", inpainted );
  41. cvSetMouseCallback( "image", on_mouse, 0 );
  42. }

效果如下:

第二步,利用封闭曲线提取图形,时间和精力都主要浪费在这一块了,最开始的想法是通过扫描线的方法获取,但最终做出来的效果差强人意,连自己这关都过不了。最后几经转折,找到了这样一个函数cvFloodFill(),这个函数可根据边界填充图像连通域,正是我所需要的。关键代码:

  1. if(event == CV_EVENT_RBUTTONUP)
  2. {
  3. cvFloodFill(maskImg,cvPoint(x,y),cvScalarAll(255));
  4. cvSaveImage("maskImg.bmp",maskImg);
  5. IplImage *segImage=cvCreateImage(cvGetSize(img),8,3);;
  6. cvCopy(img,segImage,maskImg);
  7. cvSaveImage("segImage.bmp",segImage);
  8. cvCopy(segImage,proc->img);
  9. cvReleaseImage(&segImage);
  10. cvDestroyWindow("Key Image");
  11. }

效果如下:

时间: 2024-10-06 11:45:01

OpenCV_提取图片中任意形状的区域的相关文章

从位图文件生成任意形状的窗口

http://hi.baidu.com/aidfan/blog/item/89547c4336566a1d9213c67a.html 有许多的软件的界面十分地漂亮,不仅窗口的客户区绘制得十分精细,连窗口的外形也是“奇形怪状”的,比如 Office 2000助手.Media Player 7.MediaRing Talk等等,连Winamp在应用了某些皮肤之后也不再是标准的矩形窗口,下图也是一个不规则的窗口. 那么,我们在编程的时候如何实现这一效果呢? 在众多的Windows API函数中,有一个

iOS开发类似于呱呱卡效果,手指划过的区域形成画笔。适用于取出部分图片(截图),如截取出图片中带文字的区域部分。

HKBrushShots Demo下载地址: 类似于呱呱卡效果,手指划过的路线可以刮出痕迹. ??功能: 用于取出部分图片(截图),如截取出图片中带文字的区域部分. ??效果: 截取出图片中的“你就是我的全世界”文字区域的图片: 截取出图片中那只呆萌的小犀牛??: 更多截图效果: ??使用: 1 - 首先将工程中的“HKScreenShot”文件夹拷贝至项目中. 2 - 在需要使用的类中引入头文件: #import "HKCropView.h" #import "HKLine

【Android】0行代码实现任意形状图片展示--android-anyshape

前言 在Android开发中, 我们经常会遇到一些场景, 需要以一些特殊的形状显示图片, 比如圆角矩形.圆形等等.关于如何绘制这类形状, 网上已经有很多的方案,比如自定义控件重写onDraw方法, 通过canvas的各种draw方法进行绘制等.那么, 更复杂的图形呢?比如,五角星?比如组合图形?又或者是各种奇奇怪怪的不规则图形呢?有同学会说, 如果已知不规则图形的具体形状, 那我们就可以通过连接顶点的方式, 找出path, 然后通过drawPath方法绘制出来啊.嗯...很有道理, 但是先不说有

【图像处理】提取图片中的交点数据

1. 前言 前两天老板突然给了一幅图像数据, 让我提取出其中的交点信息, 图片是这样的: 由于图像数据实在太大,就传了一张截图上来~~ 2. 处理思路 2.1 基本需求 我们的需求实际上就是, 提取图像中黑色线段相交的部分(简单来说就是相交的点) 2.2 基本思路 检测图像中的黑色直线部分, 根据hough变换提取出相应的直线方程, 根据直线方程求出他们的交点, 即为我们所需要的点.由于处理的时候, 存在一定误差, 所以一般可以分为两个步骤, 先粗略的寻找一个交点, 然后对他的周围进行搜素即可.

教你如何提取图片中的文字

在我国国民经济飞速发展的今天,软件是国民经济发展必不可少的武器,只需大力发展软件产业,才华习气我国国民经济发展的需要.捷速ocr文字辨认软件的研发人员在运用上进行不懈的极力,不断地开发出新的OCR产品,为各行业供应信息管理解决方案,为我国的基础信息化缔造供应有力的支持.ocr识别软件 好马配好鞍,好的软件也需要有高质量的文件才华得到最好的辨认率.所以,在运用捷速ocr文字辨认软件之前,应作为好充沛的准备,下面我们来看看需要准备些什么东西: 1.在放置扫描原稿时,把扫描的文字资料一定要摆放在扫描开

Android中绘制圆角矩形图片及任意形状图片

圆角矩形图片在苹果的产品中很流行,相比于普通的矩形,很多人都喜欢圆角矩形的图片,因为它避开了直角的生硬,带来更好的用户体验,下面是几个设计的例子: 下面在Android中实现将普通的矩形图片绘制成圆角矩形.首先看最终效果: 代码清单: package com.example.phototest; import android.os.Bundle; import android.app.Activity; import android.graphics.Bitmap; import android

转:java提取图片中的像素

本文转自:http://www.infosys.tuwien.ac.at/teaching/courses/WebEngineering/References/java/docs/api/java/awt/image/PixelGrabber.html PixelGrabber 类实现可以附加在 Image 或 ImageProducer 对象上获得图像像素子集的 ImageConsumer.下面是一个示例: public void handlesinglepixel(int x, int y,

C# 图片识别技术(支持21种语言,提取图片中的文字)

图片识别的技术到几天已经很成熟了,只是相关的资料很少,为了方便在此汇总一下(C#实现),方便需要的朋友查阅,也给自己做个记号. 图片识别的用途:很多人用它去破解网站的验证码,用于达到自动刷票或者是批量注册的目的,但我觉得它最吸引我的地方是可以让一些书写的东西,自动识别成电脑上的文字,比如说手拟的合同,修改过的书面论文或者是文档,每月的花费发票需要在电脑上录入或者是汇总信息,日记本上的文章要转移到电脑上等等,我们现在就不用再头痛把它们在电脑上敲写一遍了. 本文介绍两种比较主流和成熟的识别方式: 方

空间直线同任意形状椭球交点

空间直线同空间中三维椭球相交,其交点即为空间直线方程同椭球方程的解,对于空间直线方程,只要知道两点空间坐标即可,而欧拉角不为零的三维椭球方程则较难描述,但可以考虑对椭球进行变换,使其欧拉角为零,进而转化为标准椭球,标准椭球方程则容易描述,相应在对椭球进行变换的同时也许对空间直线进行相应的变换.由此,通过标准椭球方程同变换后的直线方程进行联立求解,即可获取交点坐标,下面简述求解过程及列出主要的计算公式. 约定本文采用右手系,空间旋转顺序为Z-Y-X. 原文地址:https://www.cnblog