Python编程及项目开发 第9章-项目开发_第1页
Python编程及项目开发 第9章-项目开发_第2页
Python编程及项目开发 第9章-项目开发_第3页
Python编程及项目开发 第9章-项目开发_第4页
Python编程及项目开发 第9章-项目开发_第5页
已阅读5页,还剩12页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

9.5项目开发利用OpenCV开发一个简单的图像处理系统。1.功能需求(1)文件操作:打开和保存图像文件。(2)图像调整:通过滑块进行缩放和旋转。(3)图像处理:l灰度化:将彩色图像转换为灰度图像。l二值化:将图像转换为黑白二值图像。l图像增强:通过直方图均衡化增强图像对比度。l边缘检测:使用Canny算法检测图像边缘。(4)图像重置:恢复原始图像2.项目设计(1)系统类的设计,如图9-28所示。(2)系统界面设计,如图9-29所示。3.项目实现11importsys2importos3fromPyQt5.QtWidgetsimport*4fromPyQt5.QtCoreimportQt,QPoint,QSize5importcv26importnumpyasnp78classImageProcessor(QMainWindow):9definit(self):10super().init()11self.initUI()12self.current_image=None13self.original_image=None14self.file_path=None15self.current_scale=1.0#新增:当前缩放比例16definitUI(self):17#设置窗口标题和大小18self.setWindowTitle('图像处理系统')19self.setGeometry(100,100,1000,800)2021#创建菜单栏22self.createMenus()2324#创建工具栏25self.createToolbars()2627#27#创建中央部件28central_widget=QWidget()29self.setCentralWidget(central_widget)3031#创建主布局32main_layout=QHBoxLayout(central_widget)3334#创建左侧图像显示区域35#36#创建右侧控制面板37#38control_group=QGroupBox("图像处理")39control_layout=QVBoxLayout()4041#缩放控制42#43#旋转控制44#4546#图像处理操作按钮47operations_layout=QGridLayout()4849self.binarize_btn=QPushButton("二值化")50self.binarize_btn.clicked.connect(lambda:cessImage("binarize"))51operations_layout.addWidget(self.binarize_btn,0,0)5253self.grayscale_btn=QPushButton("灰度化")54self.grayscale_btn.clicked.connect(lambda:cessImage("grayscale"))55operations_layout.addWidget(self.grayscale_btn,0,1)56#5758#添加到主布局59control_layout.addStretch()60control_group.setLayout(control_layout)61main_layout.addWidget(control_group,1)6263#状态栏64self.statusBar().showMessage('就绪')6566defcreateMenus(self):67#6869defcreateToolbars(self):70#717172defopenImage(self):73options=QFileDialog.Options()74file_path,_=QFileDialog.getOpenFileName(75self,"打开图像","","图像文件(*.png*.jpg*.jpeg*.bmp*.gif);;\76所有文件(*)",options=options)77iffile_path:78self.file_path=file_path79self.original_image=cv2.imread(file_path)80self.current_image=self.original_image.copy()81self.current_scale=1.0#重置缩放比例82self.updateImageDisplay()83self.statusBar().showMessage(f'已打开:{os.path.basename(file_path)}')85defsaveImage(self):86ifself.current_imageisNone:87QMessageBox.warning(self,"警告","没有可保存的图像")88return90options=QFileDialog.Options()91file_path,_=QFileDialog.getSaveFileName(92self,"保存图像","","PNG文件(*.png);;JPEG文件(*.jpg);;\93BMP文件(*.bmp)",options=options)9495iffile_path:96try:97#转换颜色空间(如果需要)98image_to_save=cv2.cvtColor(self.current_image,cv2.COLOR_BGR2RGB)99cv2.imwrite(file_path,image_to_save)100self.statusBar().showMessage(f'已保存:{os.path.basename(file_path)}')101exceptExceptionase:102QMessageBox.critical(self,"错误",f"保存图像失败:{str(e)}")104defzoomImage(self,value):105ifself.current_imageisNone:106return107self.zoom_value_label.setText(f"{value}%")108#计算缩放比例109new_scale=value/100.0110#基于当前图像进行缩放,而不是始终使用原始图像111ifself.current_scale!=new_scale:112height,width=self.current_image.shape[:2]113new_width=int(width*(new_scale/self.current_scale))114new_height=int(height*(new_scale/self.current_scale))115115self.current_image=cv2.resize(self.current_image,(new_width,new_height))116self.current_scale=new_scale117self.updateImageDisplay()119defrotateImage(self,value):120ifself.current_imageisNone:121return122self.rotate_value_label.setText(f"{value}°")123#获取图像中心124height,width=self.current_image.shape[:2]125center=(width//2,height//2)126#旋转矩阵127rotation_matrix=cv2.getRotationMatrix2D(center,value,1.0)128#执行旋转129self.current_image=cv2.warpAffine(self.current_image,130rotation_matrix,(width,height))132self.updateImageDisplay()134defprocessImage(self,operation):135ifself.current_imageisNone:136QMessageBox.warning(self,"警告","没有可处理的图像")137return138ifoperation=="grayscale":139self.current_image=cv2.cvtColor(self.current_image,\140cv2.COLOR_BGR2GRAY)141self.statusBar().showMessage("已应用灰度化")142elifoperation=="binarize":143iflen(self.current_image.shape)==3:144gray=cv2.cvtColor(self.current_image,cv2.COLOR_BGR2GRAY)145else:146gray=self.current_image147_,self.current_image=cv2.threshold(gray,127,255,cv2.THRESH_BINARY)148self.statusBar().showMessage("已应用二值化")149elifoperation=="enhance":150iflen(self.current_image.shape)==3:151ycrcb=cv2.cvtColor(self.current_image,cv2.COLOR_BGR2YCrCb)152channels=cv2.split(ycrcb)153channels[0]=cv2.equalizeHist(channels[0])154ycrcb=cv2.merge(channels)155self.current_image=cv2.cvtColor(ycrcb,cv2.COLOR_YCrCb2BGR)156else:157self.current_image=cv2.equalizeHist(self.current_image)158self.statusBar().showMessage("已应用图像增强")159159elifoperation=="edge":160iflen(self.current_image.shape)==3:161gray=cv2.cvtColor(self.current_image,cv2.COLOR_BGR2GRAY)162else:163gray=self.current_image165self.current_image=cv2.Canny(gray,100,200)166self.statusBar().showMessage("已应用边缘检测")168self.updateImageDisplay()170defresetImage(self):171ifself.original_imageisnotNone:172self.current_image=self.original_image.copy()173self.current_scale=1.0#重置缩放比例174self.zoom_slider.setValue(100)175self.rotate_slider.setValue(0)176self.updateImageDisplay()177self.statusBar().showMessage("图像已重置")179defundo(self):180ifself.original_imageisnotNone:181self.current_image=self.original_image.copy()182self.current_scale=1.0#重置缩放比例183self.zoom_slider.setValue(100)184self.rotate_slider.setValue(0)185self.updateImageDisplay()186self.statusBar().showMessage("已撤销所有操作")188defabout(self):189QMessageBox.about(self,"关于图像处理系统",190"图像处理系统v1.0\n\n"191"一个简单的图像处理应用程序,支持图像的打开、保存、缩放、旋转、"192"二值化、灰度化、图像增强和边缘检测等功能。\n\n"193"使用PyQt5和OpenCV开发。")195defupdateImageDisplay(self):196ifself.current_imageisNone:197return199#转换OpenCV图像为Qt图像200iflen(self.current_image.shape)==3:#彩色图像201height,width,channel=self.current_image.shape202bytes_per_line=3*width203q_203q_img=QImage(204self.current_image.data,width,height,bytes_per_line,205QImage.Format_RGB888206).rgbSwapped()207else:#灰度图像208height,width=self.current_image.shape209bytes_per_line=width210q_img=QImage(211self.current_image.data,width,height,bytes_per_line,212QImage.Format_Grayscale8213)214#在标签上显示图像215pixmap=QPixmap.fromImage(q_img)216self.image_label.setPixmap(pixmap)217218defresizeEvent(self,event):219#调整窗口大小时重新显示图像220ifself.current_imageisnotNone:221self.updateImageDisplay()222super().resizeEvent(event)223224defmain():225#确保中文显示正常226app=QApplication(sys.argv)227processor=ImageProcessor()228processor.show()229sys.exit(app.exec_())230231if__name__=='__main__':232main()233说明:QT的Qlabel不能显示PIL支持的格式的文件,因此为了在QT中显示图像,需将PIL图像转换为QImage格式的图像。1.功能需求针对一个企业的数据进行数据分析及可视化。主要功能包括:(1)销售趋势分析及可视化:l显示每日销售额变化。l添加月平均销售额标记点。l使用不同颜色标识不同元素。(2)部门绩效:l折线图展示各部门绩效分数。l柱形图显示部门预算。(3)产品销售与利润:l并列柱状图展示各产品销售额和利润。l添加利润率标签(百分比)。l直观比较不同产品的盈利能力。(4)员工销售业绩:l水平条形图展示员工销售额排名。l使用渐变色增强视觉效果。l包含销售额数值标签。(5)关键指标摘要显示:l总销售额。l平均日销售额。l最高日销售额。l员工平均销售额。2.项目设计(1)数据库设计本系统使用SQLITE3数据库(enterprise_data.db)存储数据,主要涉及4张表。lsales_data(销售数据表)字段名数据类型说明idINTEGER主键,自增整数dateDATEsalesREAL销售额ldepartments(部门数据表)字段名数据类型说明idINTEGER主键,自增整数nameTEXT部门名称budgetREAL部门预算performanceINTEGER部门绩效分数lproducts(产品销售数据表)字段名数据类型说明idINTEGER主键,自增整数nameTEXT产品名称salesREAL产品销售额profitREAL产品利润lemployees(员工销售数据表)字段名数据类型说明idINTEGER主键,自增整数nameTEXT员工姓名salesREAL员工销售额(2)系统界面设计系统界面如图9-30所示。3.项目实现1importsqlite32importnumpyasnp3importmatplotlib.pyplotasplt4fromdatetimeimportdatetime,timedelta5importmatplotlib.datesasmdates67#设置中文字体支持8plt.rcParams['font.sans-serif']=['SimHei']9plt.rcParams['axes.unicode_minus']=False10#读取企业数据11defgenerate_data():12#连接数据库13conn=sqlite3.connect('enterprise_data.db')14cursor=conn.cursor()16#从sales_data表读取销售数据17cursor.execute("SELECTdate,salesFROMsales_dataORDERBYdate")18sales_records=cursor.fetchall()1919dates=[datetime.strptime(record[0],'%Y-%m-%d')forrecordinsales_records]20sales=[record[1]forrecordinsales_records]2122#从departments表读取部门数据23cursor.execute("SELECTname,budget,performanceFROMdepartments")24dept_records=cursor.fetchall()25departments=[record[0]forrecordindept_records]26dept_budgets=[record[1]forrecordindept_records]27dept_performance=[record[2]forrecordindept_records]2829#从products表读取产品数据30cursor.execute("SELECTname,sales,profitFROMproducts")31product_records=cursor.fetchall()32products=[record[0]forrecordinproduct_records]33product_sales=[record[1]forrecordinproduct_records]34product_profit=[record[2]forrecordinproduct_records]3536#从employees表读取员工数据37cursor.execute("SELECTname,salesFROMemployees")38employee_records=cursor.fetchall()39employees=[record[0]forrecordinemployee_records]40employee_sales=[record[1]forrecordinemployee_records]4142conn.close()#关闭数据库4344return{45'dates':dates,46'sales':sales,47'departments':departments,48'dept_budgets':dept_budgets,49'dept_performance':dept_performance,50'products':products,51'product_sales':product_sales,52'product_profit':product_profit,53'employees':employees,54'employee_sales':employee_sales55}5657#计算月度平均销售额58defcalculate_monthly_average(dates,sales):59#创建按月份分组的字典60monthly_data={}61fordate,saleinzip(dates,sales):62#创建月份键(年,月)6363month_key=(date.year,date.month)64ifmonth_keynotinmonthly_data:65monthly_data[month_key]=[]6667monthly_data[month_key].append(sale)6869#计算每个月的平均销售额和日期70monthly_avg=[]71monthly_dates=[]7273formonth_key,sales_listinmonthly_data.items():74#计算平均销售额75avg_sale=sum(sales_list)/len(sales_list)7677#创建该月的中间日期(15号)78avg_date=datetime(month_key[0],month_key[1],15)7980monthly_avg.append(avg_sale)81monthly_dates.append(avg_date)83returnmonthly_dates,monthly_avg85#创建仪表板86classBusinessDashboard:87definit(self,data):88self.data=data89self.fig,self.axs=plt.subplots(2,2,figsize=(14,10))90self.fig.suptitle('企业数据分析仪表板(2024-2025)',fontsize=20,fontweight='bold')91self.create_dashboard()92plt.tight_layout(rect=[0,0,1,0.95])93plt.show()9495defcreate_dashboard(self):96#销售趋势图97self.axs[0,0].plot(self.data['dates'],self.data['sales'],'b-',linewidth=1,alpha=0.7)98self.axs[0,0].set_title('销售趋势分析',fontsize=14)99self.axs[0,0].set_xlabel('日期')100self.axs[0,0].set_ylabel('销售额(元)')101self.axs[0,0].grid(True,linestyle='--',alpha=0.7)103#添加月度平均线104monthly_dates,monthly_avg=calculate_monthly_average(self.data['dates'],\105self.data['sales'])106self.axs[0,0].plot(monthly_dates,monthly_avg,'ro-',107107markersize=6,label='月平均')109#添加图例和格式化日期110self.axs[0,0].legend()111self.axs[0,0].xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m'))113#部门预算与绩效114x=np.arange(len(self.data['departments']))115width=0.35117#预算柱状图118bars1=self.axs[0,1].bar(x-width/2,self.data['dept_budgets'],119width,label='预算',color='skyblue')121#绩效折线图(使用次坐标轴)122ax2=self.axs[0,1].twinx()123line=ax2.plot(x,self.data['dept_performance'],'ro-',124linewidth=2,markersize=8,label='绩效')126self.axs[0,1].set_title('部门预算与绩效',fontsize=14)127self.axs[0,1].set_xticks(x)128self.axs[0,1].set_xticklabels(self.data['departments'])129self.axs[0,1].set_ylabel('预算(元)')130ax2.set_ylabel('绩效分数',color='red')131ax2.tick_params(axis='y',labelcolor='red')132ax2.set_ylim(0,100)134#添加数据标签135forbarinbars1:136height=bar.get_height()137self.axs[0,1].text(bar.get_x()+bar.get_width()/2.,height,138f'{height/10000:.1f}万',139ha='center',va='bottom')141#产品销售与利润142x=np.arange(len(self.data['products']))143width=0.35145bars1=self.axs[1,0].bar(x-width/2,self.data['product_sales'],146width,label='销售额',color='lightgreen')147bars2=self.axs[1,0].bar(x+width/2,self.data['product_profit'],148width,label='利润',color='orange')150self.axs[1,0].set_title('产品销售与利润',fontsize=14)151151self.axs[1,0].set_xticks(x)152self.axs[1,0].set_xticklabels(self.data['products'])153self.axs[1,0].set_ylabel('金额(元)')154self.axs[1,0].legend()156#添加数据标签157forbarinbars1:158height=bar.get_height()159self.axs[1,0].text(bar.get_x()+bar.get_width()/2.,height,160f'{height/10000:.1f}万',161ha='center',va='bottom')163forbarinbars2:164height=bar.get_height()165self.axs[1,0].text(bar.get_x()+bar.get_width()/2.,height,166f'{height/10000:.1f}万',167ha='center',va='bottom')169#计算利润率并添加标签170fori,productinenumerate(self.data['products']):171profit_margin=self.data['product_profit'][i]/self.data['product_sales'][i]172self.axs[1,0].text(i,max(self.data['product_sales'][i],\173self.data['product_profit'][i])+50000,f'利润率:{profit_margin:.1%}',174ha='center',va='bottom'

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论