简单的图形识别demo,可以识别圆形、三角形、五角形、矩形
开源仓库
github: GitHub - AhDun/QtPatternRecognition: Qt5简单的图形识别demo
gitee:QtPatternRecognition: Qt5简单的图形识别demo
源码
analyse.c
#include "analyse.h"
analyse::analyse(QObject *parent) : QThread(parent)
{
}
void analyse::run()
{
// while(1){
// IamgeH(FileAddr);
// emit sendFile();
// IamgeLook = 1;
// while(IamgeLook);
// }
}
int analyse::channel(int h, int s, int l)
{
if(h > 240 || h < 20){
if(s > 100 && l > 100){
return 1;
}
}
else if(h > 240 || h < 20){
if(s > 100 && l > 100){
return 2;
}
}
else if(h > 240 || h < 20){
if(s > 100 && l > 100){
return 3;
}
}
return 0;
}
void analyse::Value2Write(int x, int y, bool v)
{
if (v) {
Value2[(x * 40) + (y / 8)] |= (0x80 >> (y % 8));
}
else {
Value2[(x * 40) + (y / 8)] &= ~(0x80 >> (y % 8));
}
}
bool analyse::Value2Read(int x, int y)
{
if (Value2[(x * 40) + (y / 8)] & (0x80 >> (y % 8))) {
return 1;
}
else {
return 0;
}
}
void analyse::Value2Init()
{
for(int x = 0; x < 240; x++){
for(int y = 0; y < 320 ; y++){
Value2Write(x,y,0);
}
}
}
void analyse::Iamge()
{
File = QImage(FileAddr);
File1 = QImage(":/new/prefix1/qrc/void.jpg");
File2 = QImage(":/new/prefix1/qrc/void.jpg");
File3 = QImage(":/new/prefix1/qrc/void.jpg");
int h,s,l;
int r=0,g=0,b=0;
bool along = 0;
bool alongLock = 1;
bool Lock = 0;
bool All[361];
int XMax = 0,XMin = 320;
int YMax = 0,YMin = 320;
Value2Init();
print(sprintf(printBuf(),"开始处理"));
for(int y = 0; y < 240; y++){
for(int x = 0 ; x < 320; x++){
File.pixelColor(x,y).getHsl(&h,&s,&l);
switch(channel(h,s,l)){
case 1:r++;break;
case 2:g++;break;
case 3:b++;break;
}
}
}
if(r > g && r > b){
color = 1;
}
else if(g > r && g > b){
color = 2;
}
else if(b > g && b > r){
color = 3;
}else{
color = 0;
}
for(int y = 0; y < 240; y++){
for(int x = 0 ; x < 320; x++){
File.pixelColor(x,y).getHsl(&h,&s,&l);
if(channel(h,s,l) == color){
File1.setPixelColor(x,y,QColor::fromHsl(h,s,l));
Value2Write(y,x,1);
if(XMin > x){
XMin = x;
}
if(x > XMax){
XMax = x;
//File2.setPixelColor(x,y,QColor::fromHsl(h,s,l));
}
if(YMin > y){
YMin = y;
}
if(y > YMax){
YMax = y;
//File2.setPixelColor(x,y,QColor::fromHsl(h,s,l));
}
}else{
Value2Write(y,x,0);
}
if(Value2Read(y,x)){
File2.setPixel(x,y,0x00000000);
File3.setPixelColor(x,y,QColor::fromHsl(h,s,l));
}else{
File2.setPixel(x,y,0xFFFFFFFF);
}
}
}
print(sprintf(printBuf(),"XMax:%d XMax:%d",XMax,XMin));
print(sprintf(printBuf(),"YMax:%d YMax:%d",YMax,YMin));
int cr,cx,cy;
if(XMax - XMin > YMax - YMin){
cr = (YMax - YMin)/2.5;
}else{
cr = (XMax - XMin)/2.5;
}
cx = XMin + (XMax - XMin)/2;
cy = YMin + (YMax - YMin)/2;
print(sprintf(printBuf(),"r:%d x:%d y:%d",cr,cx,cy));
for(int i = 0;i <= 360;i++){
int x = cr*cos(i*M_PI / 180) + cx;
int y = cr*sin(i*M_PI / 180) + cy;
if(Value2Read(y,x)){
//File3.setPixel(x,y,0x00000000);
All[i] = 1;
}else{
File3.setPixel(x,y,0x00000000);
All[i] = 0;
}
}
int i = 0;
angle = 0;
while(1){
if(All[i] == 1){
if(along == 0){
if(alongLock == 0){
angle++;
alongLock = 1;
print(sprintf(printBuf(),"在%d度方向,有一个角",i));
}
}
along = 1;
}else{
if(Lock == 1){
break;
}else{
if(along == 1){
alongLock = 0;
}
along = 0;
}
}
i++;
if(i >= 360){
i = 0;
if(Lock == 1){
break;
}
Lock = 1;
}
}
print(sprintf(printBuf(),"完成处理"));
}
char* analyse::printBuf()
{
for(int i = 0; i < 500;i++){
PrintBuf[i] = 0;
}
return &PrintBuf[0];
}
void analyse::print(int x)
{
PrintLook = 1;
emit snedPrint();
while(PrintLook);
}
void analyse::IStart()
{
Iamge();
emit sendFile();
qDebug() << "OK";
}
analyse.h
#ifndef ANALYSE_H
#define ANALYSE_H
#include <QWidget>
#include <QFile>
#include <QFileDialog>
#include <QImage>
#include <QPixmap>
#include <QIODevice>
#include <QDebug>
#include <QColor>
#include <QStringList>
#include <stdio.h>
#include <QTime>
#include <QThread>
#include <QObject>
#include <math.h>
class analyse : public QThread
{
Q_OBJECT
public:
analyse(QObject *parent = 0);
public:
void Iamge();
int channel(int h,int s,int l);
void Value2Init();
void Value2Write(int x,int y,bool v);
bool Value2Read(int x,int y);
void print(int x);
char* printBuf();
QImage File;
QImage File1;
QImage File2;
QImage File3;
QString FileAddr;
char Value2[320*240/8];
char PrintBuf[500];
bool PrintLook;
bool IamgeLook;
int angle;
int color;
signals:
void sendFile();
void snedPrint();
public slots:
void IStart();
protected:
void run();
};
#endif // ANALYSE_H
widget.c
#include "widget.h"
#include "ui_widget.h"
#include "analyse.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
this->setWindowTitle("图像可视化识别");
this->setFixedSize(this->size());
ui->start->setEnabled(false);
ui->start_2->setEnabled(false);
analyse1 = new analyse(this);
connect(analyse1,&analyse::sendFile,this,&Widget::receFile);
connect(analyse1,&analyse::snedPrint,this,&Widget::recePrint);
connect(this,&Widget::IStart,analyse1,&analyse::IStart);
qDebug() << QThread::currentThread();
QPalette pe;
QFont ft;
ft.setPointSize(20);
pe.setColor(QPalette::WindowText, Qt::red);
ui->result->setPalette(pe);
ui->result->setFont(ft);
}
Widget::~Widget()
{
delete ui;
delete analyse1;
}
void Widget::receFile()
{
ui->yuangimage->setPixmap(QPixmap::fromImage(analyse1->File));
ui->muimage->setPixmap(QPixmap::fromImage(analyse1->File1));
ui->yaimage->setPixmap(QPixmap::fromImage(analyse1->File2));
ui->analyse->setPixmap(QPixmap::fromImage(analyse1->File3));
ui->start->setEnabled(true);
ui->start_2->setEnabled(true);
QString result = "识别结果: ";
switch (analyse1->color) {
case 1: result.append("红色的");break;
case 2: result.append("绿色的");break;
case 3: result.append("蓝色的");break;
default:result.append("未知颜色的");break;
}
switch (analyse1->angle) {
case 0:
case 1:
result.append("圆形");break;
case 3:
result.append("三角形");break;
case 5:
result.append("五角形");break;
case 4:
result.append("矩形");break;
default:
result.append("未知形状");break;
}
ui->result->setText(result);
}
void Widget::recePrint()
{
ui->textBrowser->append(analyse1->PrintBuf);
analyse1->PrintLook = 0;
}
void Widget::on_openfile_clicked()
{
analyse1->FileAddr = QFileDialog::getOpenFileName(nullptr,tr("打开源图像"),qApp->applicationDirPath()+"/test",tr("*.png"));
ui->lineEdit->setText(analyse1->FileAddr);
emit IStart();
}
void Widget::on_start_2_clicked()
{
emit IStart();
}
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QFile>
#include <QFileDialog>
#include <QImage>
#include <QPixmap>
#include <QIODevice>
#include <QDebug>
#include <QColor>
#include <QStringList>
#include <stdio.h>
#include <QTime>
#include <QThread>
#include "analyse.h"
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
signals:
void IStart();
private slots:
void receFile();
void recePrint();
void on_openfile_clicked();
void on_start_2_clicked();
private:
Ui::Widget *ui;
analyse *analyse1;
};
#endif // WIDGET_H
widget.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Widget</class>
<widget class="QWidget" name="Widget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1402</width>
<height>709</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>1402</width>
<height>709</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>1402</width>
<height>709</height>
</size>
</property>
<property name="windowTitle">
<string>Widget</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLineEdit" name="lineEdit"/>
</item>
<item>
<widget class="QPushButton" name="openfile">
<property name="minimumSize">
<size>
<width>50</width>
<height>50</height>
</size>
</property>
<property name="text">
<string>打开文件</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="maximumSize">
<size>
<width>100</width>
<height>100</height>
</size>
</property>
<property name="text">
<string>源图像</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="yuangimage">
<property name="minimumSize">
<size>
<width>320</width>
<height>240</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>320</width>
<height>240</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgb(203, 203, 203);</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>颜色过滤</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="muimage">
<property name="minimumSize">
<size>
<width>320</width>
<height>240</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>320</width>
<height>240</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgb(203, 203, 203);</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QLabel" name="label_6">
<property name="text">
<string>压缩处理</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="yaimage">
<property name="minimumSize">
<size>
<width>320</width>
<height>240</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>320</width>
<height>240</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgb(203, 203, 203);</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<widget class="QLabel" name="label_7">
<property name="text">
<string>识别处理</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="analyse">
<property name="minimumSize">
<size>
<width>320</width>
<height>240</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>320</width>
<height>240</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgb(203, 203, 203);</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QPushButton" name="start">
<property name="minimumSize">
<size>
<width>0</width>
<height>50</height>
</size>
</property>
<property name="text">
<string>开始识别</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="start_2">
<property name="minimumSize">
<size>
<width>0</width>
<height>50</height>
</size>
</property>
<property name="text">
<string>重新处理</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QTextBrowser" name="textBrowser">
<property name="minimumSize">
<size>
<width>650</width>
<height>0</height>
</size>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="result">
<property name="minimumSize">
<size>
<width>331</width>
<height>61</height>
</size>
</property>
<property name="text">
<string>识别结果:</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>