Image reading and saving based on Qt and OpenCV, and simple edge processing result display using Canny

The first time I wrote a CSDN blog, I was doing a graduation project recently. In my spare time, I wrote a picture reading and storage and simple OpenCV edge processing. Finally, the functions of image reading, edge detection and saving are realized.


This time, Qt5.7 (the installation package name is qt-opensource-windows-x86-mingw530-5.7.1.exe) and OpenCV3.1 are used. There is not much to say about the configuration of the two environments.

1. Interface design


First create a new project mainWidget inheriting from the QWidget class as shown in the figure, and create the interface as shown in the ui file.



After compiling and running, the interface is as shown below, which is actually very simple.


2. Open and display the picture
Click the openBtn button to trigger the slot. The code is as follows:
void mainWidget::on_openBtn_clicked()
{
    QString fileName = QFileDialog::getOpenFileName(
                    this, "Open image",
                    ".",
                    "picture(*.bmp *.jpg *.pbm *.pgm *.png *.ppm *.xbm *.xpm);;all files(*.*)");
    if(fileName != "")
    {
        if(image->load(fileName))
        {
            QGraphicsScene *scene = new QGraphicsScene;
            scene->addPixmap(QPixmap::fromImage(*image));
            ui->formerView->setScene(scene);
            ui->formerView->resize(image->width() + 10, image->height() + 10);
            ui->formerView->show();
        }
        else
        {
            QMessageBox::information(this,
                            tr("Failed to open image"),
                            tr("Failed to open image!"));
            delete image; return;
        }
    }
}
3. Simple implementation and processing of OpenCV
This code is excerpted from Mao Xingyun's "Introduction to OpenCV3 Programming", but simply uses the Canny operator for edge detection.

Mat mainWidget ::Canny_check()
{
    // load original image
        cv :: Mat  srcImage;
        srcImage  =  QImage2Mat (* image );
        //----------------------------------------------------------------------------------
        // High-level canny usage, convert to grayscale image, denoise, use canny, and finally use the obtained edge as a mask, copy the original image to the effect image, and get a colored edge image	
        //----------------------------------------------------------------------------------
        Mat dstImage,edge,grayImage;
        // [1] Create a matrix of the same type and size as src (dst) 
        dstImage.create (  srcImage. size (),  srcImage.type ()  );
        // [2] Convert the original image to a grayscale image 
        cvtColor (  srcImage,  grayImage, COLOR_BGR2GRAY );  
        // [3] First use the 3x3 kernel to denoise  
        blur( grayImage, edge,Size(3,3));  
        // [4] Run the Canny operator 
        Canny( edge, edge,3,9,3);   
        //[5] Set all elements in g_dstImage to 0
        dstImage =Scalar::all(0); 
        //[6] Use the edge image g_cannyDetectedEdges output by the Canny operator as a mask to copy the original image g_srcImage to the target image g_dstImage
        srcImage.copyTo (  dstImage,  edge);
        return dstImage;
}
The processing slot (edge ​​detection button) is as follows:
void mainWidget ::on_disposeBtn_clicked()
{
    Mat  resultmat  =  Canny_check(); //resultmat complete!
    resultimage  =  Mat2QImage(resultmat); //Convert mat format to Qimage format
// ui->label->setPixmap(QPixmap::fromImage(resultimage));//Display the result on the label    
    QGraphicsScene *scene =newQGraphicsScene;  
    scene->addPixmap(QPixmap::fromImage(resultimage));
    ui->resultView->setScene(scene);
    ui->resultView->resize(resultimage.width()+10,resultimage.height()+10); 
    ui->resultView->show();
}
Among them, the format conversion functions such as the QImage2Mat function and the Mat2QImage function need to be written by themselves.
Fourth, save the processed picture The
code is as follows:
void mainWidget ::on_saveBtn_clicked()
{
    QString fileName =QFileDialog::getSaveFileName( 
                    this, "保存图片",
                    ".",
                    "图片 (*.jpg *.bmp *.pbm *.pgm *.png *.ppm *.xbm *.xpm);;所有文件(*.*)");
    if(!fileName.isEmpty())
    {
        saveFile(fileName);
    }
    else
    {
        return;
    }
}
bool mainWidget::saveFile(const QString &filename)
{
    QFile file(filename);
    if (!file.open(QIODevice::ReadWrite))
    {
        QMessageBox::warning(this,tr("保存文件"),tr("无法保存文件 %1:\n%2").arg(filename).arg(file.errorString()));
        return false;
    }
    QByteArray ba;
    QBuffer buffer(&ba);
    buffer.open(QIODevice::WriteOnly);
    resultimage.save(&buffer, "JPG");
    file.write(ba);
    QMessageBox::information(this,tr("保存文件"),tr("文件已保存至:\n%1").arg(filename));
    return true;
}
五、最终结果

六、需要改进的地方
本工程界面设计的graphicsView控件的布局不能灵活随着图片而变化。

源码在这里:http://download.csdn.net/detail/weixin_38334320/9815047

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324803271&siteId=291194637