inpainting小工具的进一步完善

9 篇文章 0 订阅
5 篇文章 0 订阅
本文介绍了对inpainting演示工具的进一步完善,包括主页面简化、处理步骤记录、添加用户自定义mask功能、鼠标事件处理、信号传递、选择形状功能、mask文件生成以及extern变量的使用。详细讨论了每一步的实现细节和技术难点。
摘要由CSDN通过智能技术生成

因为教授让我去公司做演示,需要demo,暑假弄的小框架就派上了用场,现在需要在原来的基础上进一步完善


1.原来的主页面简化,主要目的是展示新的方法,旧方法太耗时,不适合现场演示,所以去掉旧方法部分,将新方法的qgraphicsview拉大

2.重复按打开文件时及时清理各显示块内容,qlabel对应clear(), qgraphicsscene对应clear之后,qgraphicsview要调用update才能清除内容

3.处理过程中的每一步都用mat数组记录下来,按detail按钮时一个个顺序显示,增加reset按钮便于从头开始播放

3.同时按教授要求需要提供用户自定义mask的功能,所以新添form类,在form.ui内只有两个大显示块,一个为原图,一个为选处理区域及展示处理后结果的区域

form的调用在之前有提到过

在qgraphicsview内检测鼠标动向的操作,可参考视频http://www.youtube.com/watch?v=d0CDMtfefB4

建立鼠标监视区域对象的类,将对象promote到新建类,在新建类内定义鼠标各类event及相关处理函数,代码就不在这里复述了


这里出现的问题是qgraphicsview新建的类在运行时出现错误,说什么convert qobject to qwidget的问题,其实是默认新建的类的构造函数为

 explicit mouse(QObject *parent = 0);

将其中的qobject改为qwideget就可以了

4. 鼠标动作

Mouse events occur when a mouse button is pressed or released inside a widget, or when the mouse cursor is moved. Mouse move events will occur only when a mouse button is pressed down, unless mouse tracking has been enabled with QWidget::setMouseTracking().

建立mousePressEvent(QMouseEvent* ev)函数和mouseReleaseEvent()函数,鼠标在3中定义的监视区域qgraphicsview内按下和释放时产生QMouseEvent,进而调用这两个函数,并释放可传递到主页面的signal

获取鼠标位置时ev.x(),ev.y(),ev.pos()均为函数,注意前两个不要忘记加括号,第三个的返回值为QPointF类型

前面提到的位置是绝对位置,如果想要根据这些位置在鼠标区标示出来,则需要调用mapToScene(ev.pos())函数,这样返回的位置是相对于qgraphicsview内scene的位置。

void mouse::mousePressEvent(QMouseEvent* ev){
    QPointF start_point= mapToScene(ev->pos());
    this->x=start_point.x();
    this->y=start_point.y();
    emit Mouse_Pressed();
}

5.鼠标信号传递到主页面

在主页面类里创建鼠标按下时,主页面要产生的动作 

private slots:
    void Mouse_Pressed();
    void Mouse_Released();
 

在主页面的构造函数内将监视区域产生的signal与主页面的动作相连。

    connect(ui->resultView_proposed_user,SIGNAL(Mouse_Pressed()),this,SLOT(Mouse_Pressed()));
    connect(ui->resultView_proposed_user,SIGNAL(Mouse_Released()),this,SLOT(Mouse_Released()));
 

6.根据鼠标运动,选择以显示的图像的一部分,并表示出来。

在qgraphicsscene内添加item,并在qgraphicsview里显示新的scene

setBrush(QBrush(Qt::blue)), 可设置填充颜色

a)b)的情况一次鼠标按下和释放定义的区域如果不满意,再次选择时需要及时清除上次的选择记录。不确定是不是有办法只去除scene中的一个item而不影响原图像,我采用的比较单纯的方法,在按下鼠标时清除全部scene,然后只显示原图像

    resultScene_proposed_user->clear();
    resultScene_proposed_user->addPixmap(*pix_user);
    ui->resultView_proposed_user->show();
 

a)以鼠标按下点和释放点为界,选择方形区域。

        QGraphicsRectItem* item_rect=new QGraphicsRectItem(ui->resultView_proposed_user->x,ui->resultView_proposed_user->y,ui->resultView_proposed_user->width,ui->resultView_proposed_user->height);
        item_rect->setBrush(QBrush(Qt::blue));
        resultScene_proposed_user->addItem(item_rect);
        ui->resultView_proposed_user->show();
 

b)以鼠标按下点和释放点为界,选择椭圆形区域。

        QGraphicsEllipseItem* item_elli=new QGraphicsEllipseItem(ui->resultView_proposed_user->x,ui->resultView_proposed_user->y,ui->resultView_proposed_user->width,ui->resultView_proposed_user->height);
        item_elli->setBrush(QBrush(Qt::red));
        resultScene_proposed_user->addItem(item_elli);
        ui->resultView_proposed_user->show();
 椭圆形item的创建方法中,参数可以设定为方形区域 

Constructs a QGraphicsEllipseItem using rect as the default rectangle. parent is passed to QAbstractGraphicsShapeItem's constructor.

c)选择所以鼠标经过的区域。

待续!

7.因为6中提到了三种不同形状的选择方式,所以在主页面中添加checkbox,允许用户选择相应的选择形状。

     

事先选择将一个checkbox选成checked,所有checkbox都选为autoExclusive,可以保证有初始值,且不会存在同时选了两个形状的情况

8. 根据鼠标选择的部位建立新的mask文件,用于Inpainting.

建立文件之前先判断选择区域是否合法,有没有超出原图像的范围;文件建立之后判断是否创建成功

a)方形区域

           Rect roi(ui->resultView_proposed_user->x,ui->resultView_proposed_user->y,ui->resultView_proposed_user->width,ui->resultView_proposed_user->height);
            Mat pixel_roi=image(roi);
            pixel_roi=Scalar(255,255,255);
 

b)椭圆形区域

            cv::RotatedRect roi=cv::RotatedRect(Point2f(ui->resultView_proposed_user->x+ui->resultView_proposed_user->width/2,ui->resultView_proposed_user->y+ui->resultView_proposed_user->height/2),Size2f(ui->resultView_proposed_user->width,ui->resultView_proposed_user->height),0);
            cv::ellipse(image,roi,Scalar(255,255,255),CV_FILLED,8);
 cv::ellipse要求的roi为rotatedrect类型,rotatedrect构造函数第一个参量为Point2f类型,定义中心点;第二个参量为size2f,定义长短轴;第三个参量为选择角度 

cv::ellipse函数第四个参量cv_filled表示颜色填充到椭圆内部,否则定义的颜色只针对椭圆边缘线

c)任意形状区域

待续!

9. 新增的自定义主页面需要调用起始主页面中定义的全局变量和函数,如canny edge detector等,如果不在自定义主页面重新定义,则调用无效;如果跟起始页面一样定义,则提示重复定义错误。

解决方法是在新增页面里将起始主页面以定义,并被新增页面需要的参量定义为extern 类型,即

extern std::string mask_name;
extern double f;
extern void CannyThreshold(int, void*);

extern可以置于变量或函数前,以在别的文件中标识变量或函数的定义,并提示编译器遇到此变量或函数时在其他模块中寻找其定义。extern是C、C++语言中表明函数和全局变量作用范围(可见性)的关键字。对于extern变量来说,仅仅是一个变量的声明,其并不是定义,不会分配内存空间。

关于extern和static区别可参见http://blog.csdn.net/zhangzheng0413/article/details/7569226

10.目前结果

起始页面:



新增页面:


11. 下一步,完成选择随意区域,美化界面

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值