Linux下基于opencv with qt的深度学习标记小程序

本文介绍了一款基于OpenCV的深度学习图片标注工具的开发过程。该工具支持用户通过键盘快捷键对图片上的特定点进行标记,并能保存标记结果以便后续的数据集训练使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

学习需要总结和交流。最近在做深度学习方面的工作,需要写一个标记小程序。编程期间参考了很多blog,终于完成了这个程序。想通过我的第一篇blog分享出去,和大家多多交流,同时自己也总结一下收获。好了,下面正式开始。

编程之前,我的目的是要实现一个能够根据键盘按键来标记图片上不同点的程序,同时能够方便地保存以及切换到下一张图片。

我想到的第一个问题是如何读取键盘按键,有两个方法:

1、opencv中waitKey()函数

2、C++的cin,getchar,getline等。

考虑到需要边读取键盘按键,边标记程序,起初我想通过pthread创建子线程来读取键盘按键。利用第二种读取方法读键值,遇到问题:linux的终端在opencv窗口后面,需要切换窗口还有输入结束符号,麻烦,放弃。这种情况下使用waitKey()函数发现waitKey需要显示一个opencv窗口才可以,也放弃了。

最终我的实现方案:主程序利用while循环waitKey函数读取键盘按键,利用opencv窗口函数实现图片标记。

#include <iostream>
#include <opencv2/opencv.hpp>
#include <string>  
#include <vector>  
#include <sys/stat.h>  
#include <sys/types.h> 


#define WINDOW_NAME "PICTURE"       

#define RED 1
#define GREEN 2
#define BLUE 3
#define ERASER 999

using namespace std;
using namespace cv;




Point point;
bool g_bDrawingBox = false;
bool g_button = false;
bool next = true;

int CurColor;
int colValue = 0;
int curKey; 
int colorR = 0;
int imgNum = 0;

Mat resImage;
Mat srcImage;
Mat tempImage;

void on_MouseHandle(int event, int x, int y, int flags, void* param);
void DrawPoint( cv::Mat& img, cv::Point point,int color );
void SetGreyValue(cv::Mat& img, cv::Point point,int color );
vector<Mat> read_images_in_folder(cv::String pattern);

int main()
{
     bool curSaveFlag = false;
        //遍历文件夹搜寻图片
	cv::String pattern = "/home/lwh/Project/MarkChip/build/chipimg/*.bmp";
	cv::String savedirstr = "/home/lwh/Project/MarkChip/build/chipimg_label/";
		
 //linux系统函数mkdir函数创建标记后的图片 
	if(0 == mkdir( savedirstr.c_str(),S_IRWXU))
	{
		cout <<"Create dir successfully!" <<endl;
	}
	else
	{
		cout <<"Can't create dir!" <<endl;
	}
  cv::String curImgName;
    vector<cv::String> fn;
      glob(pattern, fn, false);
      size_t count = fn.size(); //number of png files in images folder
    
    
    //设置鼠标操作回调函数
    
            
   while(1)
   {
        
        if(next)
        {
            srcImage = imread(fn[imgNum]);
            srcImage.copyTo(tempImage);
            resImage = Mat::zeros(srcImage.size(),CV_8UC1);
            size_t bmppos = fn[imgNum].find("chipimg");
            curImgName = fn[imgNum].substr(bmppos + 8,1000);
            cout << curImgName <<endl;    
            namedWindow( WINDOW_NAME );
            imshow(WINDOW_NAME,tempImage);
            setMouseCallback(WINDOW_NAME,on_MouseHandle,(void*)&tempImage);
            next = false;
        }
        curKey  = waitKey(10);
        switch(curKey)
        {
            case 122://z
            case 90://Z
            {
                CurColor = RED;
                colValue = 1;
                g_button = true;
            }
            break;
            case 120://x
            case 88://X
            {
                CurColor = GREEN;
                colValue = 2;
                g_button = true;
            }
            break;
            case 99://c
            case 67://C
            {
                CurColor = BLUE;
                colValue = 3;
                g_button = true;
            }
            break;
            case 118://v
            case 86://V
            {
                CurColor = 3;
                colValue = 0;
                g_button = true;
            }
            break;
            case 81:
            case 113:
            {
                CurColor = ERASER;
                g_button = true;
            }
            break;
        //调整画笔大小
            case 48:
            case 49:
            case 50:
            case 51:
            case 52:
            case 53:            
            case 54:
            case 55:
            case 56:
            case 57:
            case 58:
            {
                colorR = curKey-48;
                cout << "The current pencil radius:"<< colorR<< endl;            
            }
            break;
            //S键,save    
            
            case 115:
            {
                cv::String filename = savedirstr + curImgName;
                try
                {
                    imwrite(filename,resImage);
                }catch(runtime_error& ex)
                {
                    cout<< "Can't save picture "<< imgNum << ex.what() << endl;
            
                }    
                curSaveFlag = true;
                cout<< "Save picture "<< imgNum << ":"<< filename <<" successfully!" << endl;
                    
            }
            break;
            //->和\|/键,下一张    
            //case 83:
            case 100:
            {
                if(!curSaveFlag)
                {
                    cout << "WARNNING! The current image hasn't been saved!"<< endl;
                }else
                {
                    imgNum++;
                    cout << "The current image number is :" << imgNum << endl; 
                    curSaveFlag = false;
                    next = true;
                    resImage.release();
                    srcImage.release();
                    tempImage.release();
                    destroyWindow(WINDOW_NAME)    ;
                }    
            }
            break;    
            default:
            {
                CurColor = 0;
                g_button = false;
                break;
            }
        }  
        
        if( curKey == 27 ) break;//按下ESC键,程序退出
    }
    return 0;
}

void on_MouseHandle(int event, int x, int y, int flags, void* param)
{
    Mat& image = *(cv::Mat*) param; 
    switch( event)
    {
        //鼠标移动消息
        case EVENT_MOUSEMOVE: 
        {      
                  if( g_button )
            {
                 g_bDrawingBox = true;                 
                 point.x = x;
                 point.y = y;
                 DrawPoint(image, point,CurColor);
                 SetGreyValue(resImage, point,CurColor );
                 //resImage.at<uchar>(y,x) = 250;
            }
        }
        break;
        //左键按下消息
        case EVENT_LBUTTONDOWN: 
        {
            if(g_button)
            {
                g_bDrawingBox = true;
                SetGreyValue(resImage, point,CurColor );
            }
        }
        break;
        //左键抬起消息
        case EVENT_LBUTTONUP: 
        {   
            g_bDrawingBox = false;
            g_button = false;
        }
        break;
    }
}
void SetGreyValue(cv::Mat& img, cv::Point point,int color )
{
switch(color)
    {
        case RED:
        {
            img.at<uchar>(point) = 250;
        }
        break;
        case GREEN:
        {
            img.at<uchar>(point) = 128;
        }
        break;
        case BLUE:
        {
            img.at<uchar>(point) = 64;
        }
        break;
        //清除某一点
        case ERASER:
        {
            cv::circle(img,point,0,0,-1);    
        }
        break;
        default:
            cv::circle(img,point,colorR,cv::Scalar(0,0,255),-1);
        break;
    }
}
void DrawPoint( cv::Mat& img, cv::Point point,int color )
//cvScaler::BGR
{
    switch(color)
    {
        case RED:
        {
            cv::circle(img,point,colorR,cv::Scalar(0,0,255),-1);
        }
        break;
        case GREEN:
        {
            cv::circle(img,point,colorR,cv::Scalar(0,255,0),-1);
        }
        break;
        case BLUE:
        {
            cv::circle(img,point,colorR,cv::Scalar(255,0,0),-1);
        }
        break;
        //清除某一点
        case ERASER:
        {
            cv::circle(img,point,0,srcImage.at<Vec3b>(point),-1);
            for(int i =-colorR;i<colorR;i++)
            {
                for(int j =-colorR;j<colorR;j++)
                {
                    Point tempoint= Point(point.x+i,point.y+j);
                    cv::circle(img,tempoint,0,srcImage.at<Vec3b>(tempoint),-1);
                }
            
            }            
        }
        break;
        default:
            cv::circle(img,point,colorR,cv::Scalar(0,0,255),-1);
        break;
    }
    //图像融合显示
    //IplImage IMG;
//    addWeighted(IplImage(srcImage),0.5,IplImage(img),0.5,IMG);
    Mat IMG;
    addWeighted(srcImage,0.8,img,0.2,0,IMG);
    imshow( WINDOW_NAME, IMG );
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值