图像手工画效果【QT+OpenCV】

效果如下

【木雕】


【铅笔画】


【素描】


【实现工具】

QT+OpenCV

【源代码】


【木雕】

void MainWindow::on_woodCarving_triggered()
{
    //木雕效果
    //如果当前点的像素值与临近任意一点的像素值大于阈值(这里设置为30),置白色;否则,置黑色
    Mat dst(srcImage.rows,srcImage.cols,CV_8UC1);
    Mat src;
    cvtColor(srcImage,src,CV_RGB2GRAY);
    for (int i=1; i<src.rows-1; i++)
    {

        uchar *current = src.ptr<uchar>(i);
        uchar *currentBefore = src.ptr<uchar>(i-1);
        uchar *currentNext = src.ptr<uchar>(i+1);
        //   uchar *currentNext = src.ptr<uchar>(i+1);
        uchar *dstLine = dst.ptr<uchar>(i);
        for (int j=1; j<src.cols-1; j++)
        {
            int a,b,c,d,e,f,g,h;
            a=abs(current[j]-currentBefore[(j-1)]);
            b=abs(current[j]-currentBefore[j]);
            c=abs(current[j]-currentBefore[(j+1)]);
            d=abs(current[j]-currentNext[(j-1)]);
            e=abs(current[j]-currentNext[(j)]);
            f=abs(current[j]-currentNext[(j+1)]);
            g=abs(current[j]-current[(j-1)]);
            h=abs(current[j]-current[(j+1)]);
            /*
            for(int m=-1;m<2;m++)
                for(int n=-1;n<2;n++)
                */
            /*
             *  //如果不先进行灰度处理,可以采用如下方式。对每一个RGB分量进行处理。
            for(int k=0;k<3;k++)
            {
                sum+=abs(current[3*j+k]-currentBefore[3*(j-1)+k]);
                sum+=abs(current[3*j+k]-currentBefore[3*j+k]);
                sum+=abs(current[3*j+k]-currentBefore[3*(j+1)+k]);
                sum+=abs(current[3*j+k]-currentNext[3*(j-1)+k]);
                sum+=abs(current[3*j+k]-currentNext[3*(j)+k]);
                sum+=abs(current[3*j+k]-currentNext[3*(j+1)+k]);
                sum+=abs(current[3*j+k]-current[3*(j-1)+k]);
                sum+=abs(current[3*j+k]-current[3*(j+1)+k]);
            }
            */
            if(a>30||b>30||c>30||d>30||e>30||f>30||g>30||h>30)
                dstLine[j]=255;
            else
                dstLine[j]=0;
        }
    }
    // dst.copyTo(dst);
    cv::Size    dsize=Size(ui->label2->width(),ui->label2->height());
    cv::resize(dst,dst,dsize);
    /*imshow("src",src);
      imshow("dst",dst);
      */
    //showLabel(dst,ui->label2);
    // imshow("dst",dst);
    img = QImage((const unsigned char*)(dst.data),dst.cols,dst.rows,dst.cols*dst.channels(), QImage::Format_Indexed8);
    //l.clear();
    ui->label2->clear();
    //img=  img.scaled(l.width(),l.height());
    // img=img.scaled(ui->label2->width(),ui->label2->height());
    //l.setPixmap(QPixmap::fromImage(img));
    ui->label2->setPixmap(QPixmap::fromImage(img));
}

【铅笔画】

void MainWindow::on_pencil_triggered()
{
    //铅笔画
    //如果当前点的像素值与临近任意一点的像素值大于阈值(这里设置为30),置黑色;否则,置白色
    //这里和木雕是相反的操作。
    Mat dst(srcImage.rows,srcImage.cols,CV_8UC1);
    Mat src;
    cvtColor(srcImage,src,CV_RGB2GRAY);
    for (int i=1; i<src.rows-1; i++)
    {
        uchar *current = src.ptr<uchar>(i);
        uchar *currentBefore = src.ptr<uchar>(i-1);
        uchar *currentNext = src.ptr<uchar>(i+1);
        //   uchar *currentNext = srcImage.ptr<uchar>(i+1);
        uchar *dstLine = dst.ptr<uchar>(i);
        for (int j=1; j<src.cols-1; j++)
        {
            int a,b,c,d,e,f,g,h;
            a=abs(current[j]-currentBefore[(j-1)]);
            b=abs(current[j]-currentBefore[j]);
            c=abs(current[j]-currentBefore[(j+1)]);
            d=abs(current[j]-currentNext[(j-1)]);
            e=abs(current[j]-currentNext[(j)]);
            f=abs(current[j]-currentNext[(j+1)]);
            g=abs(current[j]-current[(j-1)]);
            h=abs(current[j]-current[(j+1)]);
            /*
            for(int m=-1;m<2;m++)
                for(int n=-1;n<2;n++)
                */
            /*
             *  //如果不先进行灰度处理,可以采用如下方式。对每一个RGB分量进行处理。
            for(int k=0;k<3;k++)
            {
                sum+=abs(current[3*j+k]-currentBefore[3*(j-1)+k]);
                sum+=abs(current[3*j+k]-currentBefore[3*j+k]);
                sum+=abs(current[3*j+k]-currentBefore[3*(j+1)+k]);
                sum+=abs(current[3*j+k]-currentNext[3*(j-1)+k]);
                sum+=abs(current[3*j+k]-currentNext[3*(j)+k]);
                sum+=abs(current[3*j+k]-currentNext[3*(j+1)+k]);
                sum+=abs(current[3*j+k]-current[3*(j-1)+k]);
                sum+=abs(current[3*j+k]-current[3*(j+1)+k]);
            }
            */

            if(a>30||b>30||c>30||d>30||e>30||f>30||g>30||h>30)
                dstLine[j]=0;
            else
                dstLine[j]=255;
        }
    }
    cv::Size    dsize=Size(ui->label2->width(),ui->label2->height());
    cv::resize(dst,dst,dsize);
    /*imshow("srcImage",srcImage);
      imshow("dstImage",dstImage);
      */
    //showLabel(dstImage,ui->label2);
    // imshow("dstImage",dstImage);
    img = QImage((const unsigned char*)(dst.data),dst.cols,dst.rows,dst.cols*dst.channels(), QImage::Format_Indexed8);
    //l.clear();
    ui->label2->clear();
    //img=  img.scaled(l.width(),l.height());
    // img=img.scaled(ui->label2->width(),ui->label2->height());
    //l.setPixmap(QPixmap::fromImage(img));
    ui->label2->setPixmap(QPixmap::fromImage(img));
}

【素描】

void MainWindow::on_sketch_triggered()
{
    //素描
    Mat src;
    srcImage.copyTo(src);
    int width=src.cols;
    int heigh=src.rows;
    Mat gray0,gray1;
    cvtColor(src,gray0,CV_BGR2GRAY);   //灰度处理
    addWeighted(gray0,-1,NULL,0,255,gray1);    //反色
    //   threshold(gray0,gray1,128,255,THRESH_BINARY_INV);
    GaussianBlur(gray1,gray1,Size(11,11),0);   //高斯处理一下
    Mat dst(gray1.size(),CV_8UC1);
    for (int y=0; y<heigh; y++)
    {
        uchar* P0  = gray0.ptr<uchar>(y);
        uchar* P1  = gray1.ptr<uchar>(y);
        uchar* P  = dst.ptr<uchar>(y);
        for (int x=0; x<width; x++)
        {
            int tmp0=P0[x];
            int tmp1=P1[x];
            P[x] =(uchar) min((tmp0+(tmp0*tmp1)/(256-tmp1)),255);   //计算
        }
    }
    cv::Size dsize=Size(ui->label2->width(),ui->label2->height());
    cv::resize(dst,dstImage,dsize);
    //   cv::cvtColor(m,m,CV_BGR2RGB);
    img = QImage((const unsigned char*)(dstImage.data),dstImage.cols,dstImage.rows,dstImage.cols*dstImage.channels(), QImage::Format_Indexed8);
    //l.clear();
    ui->label2->clear();
    //img=  img.scaled(l.width(),l.height());
    // img=img.scaled(ui->label2->width(),ui->label2->height());
    //l.setPixmap(QPixmap::fromImage(img));
    ui->label2->setPixmap(QPixmap::fromImage(img));
    /*
    imshow("a",dst);
    waitKey();
*/
}

参考资料

1.http://www.douban.com/group/topic/28961821/

2.http://blog.csdn.net/column/details/stylizefliter.html

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Qt是一种跨平台的应用程序开发框架,而OpenCV是计算机视觉和图像处理库。这两者的结合可以实现图像显示。 首先,我们需要在Qt项目中集成OpenCV库。我们可以在pro文件中添加如下代码来链接OpenCV库: ``` LIBS += -lopencv_core LIBS += -lopencv_highgui ``` 接下来,在Qt的窗口部件中添加一个标签控件用于显示图像。我们可以在Qt设计师中拖拽一个QLabel控件到窗口中,并为其设置一个固定大小。 然后,在Qt代码中,我们可以使用OpenCV加载图像,并将其转换为Qt可以显示的格式,如QImage。代码示例如下: ```cpp #include <QVBoxLayout> #include <QLabel> #include <QImage> #include <opencv2/opencv.hpp> ... // 创建一个标签控件 QLabel *imageLabel = new QLabel(this); // 加载图像 cv::Mat image = cv::imread("path_to_image.jpg"); // 将OpenCV图像转换为Qt图像 QImage qImage(image.data, image.cols, image.rows, image.step, QImage::Format_RGB888); // 将图像设置到标签控件中显示 imageLabel->setPixmap(QPixmap::fromImage(qImage)); // 添加布局并将标签控件添加到布局中 QVBoxLayout *layout = new QVBoxLayout(this); layout->addWidget(imageLabel); setLayout(layout); ``` 最后,我们需要在窗口中显示图像,可以调用`show()`函数进行显示: ```cpp show(); ``` 编译和运行代码后,将会在Qt窗口中显示出加载的图像。 总结起来,使用QtOpenCV结合可以实现图像的显示。我们需要集成OpenCV库,使用`QLabel`控件来显示图像,并将OpenCV图像转换为Qt图像格式,最后将图像设置到标签控件中进行显示。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

superdont

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值