diff --git a/QuickDraw在线交互识别系统/homeworks/水质检测.ipynb b/QuickDraw在线交互识别系统/homeworks/水质检测.ipynb new file mode 100644 index 0000000..06637cc --- /dev/null +++ b/QuickDraw在线交互识别系统/homeworks/水质检测.ipynb @@ -0,0 +1,564 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "78c67687", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['images/1_1.jpg',\n", + " 'images/1_10.jpg',\n", + " 'images/1_11.jpg',\n", + " 'images/1_12.jpg',\n", + " 'images/1_13.jpg',\n", + " 'images/1_14.jpg',\n", + " 'images/1_15.jpg',\n", + " 'images/1_16.jpg',\n", + " 'images/1_17.jpg',\n", + " 'images/1_18.jpg',\n", + " 'images/1_19.jpg',\n", + " 'images/1_2.jpg',\n", + " 'images/1_20.jpg',\n", + " 'images/1_21.jpg',\n", + " 'images/1_22.jpg',\n", + " 'images/1_23.jpg',\n", + " 'images/1_24.jpg',\n", + " 'images/1_25.jpg',\n", + " 'images/1_26.jpg',\n", + " 'images/1_27.jpg',\n", + " 'images/1_28.jpg',\n", + " 'images/1_3.jpg',\n", + " 'images/1_30.jpg',\n", + " 'images/1_31.jpg',\n", + " 'images/1_32.jpg',\n", + " 'images/1_33.jpg',\n", + " 'images/1_34.jpg',\n", + " 'images/1_35.jpg',\n", + " 'images/1_36.jpg',\n", + " 'images/1_37.jpg',\n", + " 'images/1_38.jpg',\n", + " 'images/1_39.jpg',\n", + " 'images/1_4.jpg',\n", + " 'images/1_40.jpg',\n", + " 'images/1_41.jpg',\n", + " 'images/1_42.jpg',\n", + " 'images/1_43.jpg',\n", + " 'images/1_44.jpg',\n", + " 'images/1_45.jpg',\n", + " 'images/1_46.jpg',\n", + " 'images/1_47.jpg',\n", + " 'images/1_48.jpg',\n", + " 'images/1_49.jpg',\n", + " 'images/1_5.jpg',\n", + " 'images/1_51.jpg',\n", + " 'images/1_6.jpg',\n", + " 'images/1_7.jpg',\n", + " 'images/1_8.jpg',\n", + " 'images/1_9.jpg',\n", + " 'images/2_1.jpg',\n", + " 'images/2_10.jpg',\n", + " 'images/2_12.jpg',\n", + " 'images/2_13.jpg',\n", + " 'images/2_14.jpg',\n", + " 'images/2_15.jpg',\n", + " 'images/2_17.jpg',\n", + " 'images/2_18.jpg',\n", + " 'images/2_19.jpg',\n", + " 'images/2_2.jpg',\n", + " 'images/2_20.jpg',\n", + " 'images/2_21.jpg',\n", + " 'images/2_22.jpg',\n", + " 'images/2_23.jpg',\n", + " 'images/2_24.jpg',\n", + " 'images/2_26.jpg',\n", + " 'images/2_27.jpg',\n", + " 'images/2_28.jpg',\n", + " 'images/2_29.jpg',\n", + " 'images/2_3.jpg',\n", + " 'images/2_30.jpg',\n", + " 'images/2_31.jpg',\n", + " 'images/2_32.jpg',\n", + " 'images/2_33.jpg',\n", + " 'images/2_34.jpg',\n", + " 'images/2_35.jpg',\n", + " 'images/2_36.jpg',\n", + " 'images/2_37.jpg',\n", + " 'images/2_38.jpg',\n", + " 'images/2_39.jpg',\n", + " 'images/2_4.jpg',\n", + " 'images/2_40.jpg',\n", + " 'images/2_41.jpg',\n", + " 'images/2_42.jpg',\n", + " 'images/2_43.jpg',\n", + " 'images/2_44.jpg',\n", + " 'images/2_5.jpg',\n", + " 'images/2_6.jpg',\n", + " 'images/2_7.jpg',\n", + " 'images/2_8.jpg',\n", + " 'images/2_9.jpg',\n", + " 'images/3_10.jpg',\n", + " 'images/3_11.jpg',\n", + " 'images/3_12.jpg',\n", + " 'images/3_13.jpg',\n", + " 'images/3_14.jpg',\n", + " 'images/3_15.jpg',\n", + " 'images/3_16.jpg',\n", + " 'images/3_17.jpg',\n", + " 'images/3_18.jpg',\n", + " 'images/3_19.jpg',\n", + " 'images/3_20.jpg',\n", + " 'images/3_21.jpg',\n", + " 'images/3_22.jpg',\n", + " 'images/3_23.jpg',\n", + " 'images/3_25.jpg',\n", + " 'images/3_26.jpg',\n", + " 'images/3_27.jpg',\n", + " 'images/3_28.jpg',\n", + " 'images/3_29.jpg',\n", + " 'images/3_3.jpg',\n", + " 'images/3_30.jpg',\n", + " 'images/3_31.jpg',\n", + " 'images/3_32.jpg',\n", + " 'images/3_34.jpg',\n", + " 'images/3_38.jpg',\n", + " 'images/3_40.jpg',\n", + " 'images/3_42.jpg',\n", + " 'images/3_43.jpg',\n", + " 'images/3_44.jpg',\n", + " 'images/3_45.jpg',\n", + " 'images/3_46.jpg',\n", + " 'images/3_47.jpg',\n", + " 'images/3_48.jpg',\n", + " 'images/3_49.jpg',\n", + " 'images/3_5.jpg',\n", + " 'images/3_50.jpg',\n", + " 'images/3_51.jpg',\n", + " 'images/3_52.jpg',\n", + " 'images/3_53.jpg',\n", + " 'images/3_55.jpg',\n", + " 'images/3_56.jpg',\n", + " 'images/3_57.jpg',\n", + " 'images/3_58.jpg',\n", + " 'images/3_59.jpg',\n", + " 'images/3_65.jpg',\n", + " 'images/3_66.jpg',\n", + " 'images/3_7.jpg',\n", + " 'images/3_71.jpg',\n", + " 'images/3_72.jpg',\n", + " 'images/3_73.jpg',\n", + " 'images/3_74.jpg',\n", + " 'images/3_75.jpg',\n", + " 'images/3_76.jpg',\n", + " 'images/3_77.jpg',\n", + " 'images/3_78.jpg',\n", + " 'images/3_8.jpg',\n", + " 'images/3_9.jpg',\n", + " 'images/4_10.jpg',\n", + " 'images/4_11.jpg',\n", + " 'images/4_13.jpg',\n", + " 'images/4_14.jpg',\n", + " 'images/4_21.jpg',\n", + " 'images/4_6.jpg',\n", + " 'images/4_7.jpg',\n", + " 'images/4_9.jpg',\n", + " 'images/5_1.jpg',\n", + " 'images/5_2.jpg',\n", + " 'images/5_3.jpg',\n", + " 'images/5_4.jpg',\n", + " 'images/5_5.jpg',\n", + " 'images/5_6.jpg']" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import re\n", + "import numpy as np\n", + "import os\n", + "import cv2\n", + "import matplotlib.pyplot as plt\n", + "\n", + "plt.rcParams['font.sans-serif'] = ['SimHei']\n", + "plt.rcParams['axes.unicode_minus'] = False\n", + "\n", + "def getimgnames(path=None):\n", + " \"\"\"\n", + " 获取指定文件夹中的JPG图片名称(含路径)\n", + " :param path: 指定文件夹\n", + " :return: path中的所有JPG图片名称(含路径,例如:./path/image1.jpg)\n", + " \"\"\"\n", + " imgnames = []\n", + " filenames = os.listdir(path) # 获取path中的所有文件名\n", + " for i in filenames:\n", + " if re.findall('\\.jpg$', i) != []: # 在所有文件名中找出JPG图片名称\n", + " imgnames.append(os.path.join(path, i)) # 将图片名称和路径合并、保存\n", + " return imgnames\n", + "\n", + "imglist = getimgnames('images/')\n", + "imglist" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "356b558c", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'\\ndef cut_image(img, imgFile):\\n cx = int(np.size(img, 1))/2\\n cy = int(np.size(img, 0))/2\\n \\n plt.figure(figsize=(8,8))\\n plt.imshow(img)\\n\\n plt.plot([cx-50, cx+50], [cy+50, cy+50], \\'r\\', linewidth=2)\\n plt.plot([cx+50, cx+50], [cy-50, cy+50], \\'r\\', linewidth=2)\\n plt.plot([cx-50, cx+50], [cy-50, cy-50], \\'r\\', linewidth=2)\\n plt.plot([cx-50, cx-50], [cy-50, cy+50], \\'r\\', linewidth=2)\\n plt.annotate(\\'选取的水样窗口\\', xy=(cx+50,cy-50), xytext=(cx+300, cy-300),\\n arrowprops=dict(facecolor=\\'black\\', shrink=0.1))\\n\\n plt.title(\\'水色样本 \\'+imgFile+\\' 分辨率为\\'+str(img.size)+\" 类别标签 \"+str(imgFile[9]))\\n plt.show()\\n \\nfor i in range(len(imglist)):\\n img = cv2.imread(imglist[i])\\n cut_image(img, imglist[i])\\n'" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "\"\"\"\n", + "def cut_image(img, imgFile):\n", + " cx = int(np.size(img, 1))/2\n", + " cy = int(np.size(img, 0))/2\n", + " \n", + " plt.figure(figsize=(8,8))\n", + " plt.imshow(img)\n", + "\n", + " plt.plot([cx-50, cx+50], [cy+50, cy+50], 'r', linewidth=2)\n", + " plt.plot([cx+50, cx+50], [cy-50, cy+50], 'r', linewidth=2)\n", + " plt.plot([cx-50, cx+50], [cy-50, cy-50], 'r', linewidth=2)\n", + " plt.plot([cx-50, cx-50], [cy-50, cy+50], 'r', linewidth=2)\n", + " plt.annotate('选取的水样窗口', xy=(cx+50,cy-50), xytext=(cx+300, cy-300),\n", + " arrowprops=dict(facecolor='black', shrink=0.1))\n", + "\n", + " plt.title('水色样本 '+imgFile+' 分辨率为'+str(img.size)+\" 类别标签 \"+str(imgFile[9]))\n", + " plt.show()\n", + " \n", + "for i in range(len(imglist)):\n", + " img = cv2.imread(imglist[i])\n", + " cut_image(img, imglist[i])\n", + "\"\"\"\n" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "85e7fe5e", + "metadata": {}, + "outputs": [], + "source": [ + "# 加载图像统计信息模块(注:也可以直接通过颜色通道来计算)\n", + "from PIL import ImageStat,Image\n", + "\n", + "# 遍历全体图像进行快速检查\n", + "size = 100\n", + "imgPath = './images'\n", + "imgWidth = [] # 图像宽度\n", + "imgHeight = [] # 图像高度\n", + "imgRrange = [] # 图像红色通道极差\n", + "imgGrange = [] # 图像绿色通道极差\n", + "imgBrange = [] # 图像蓝色通道极差\n", + "\n", + "newImgs = [] # 获得选取后的图像作为模型训练和验证数据\n", + "\n", + "imgFiles = os.listdir(imgPath)\n", + "for imgFile in imgFiles:\n", + " img = Image.open(os.path.join(imgPath,imgFile))\n", + " imgWidth.append(img.size[0])\n", + " imgHeight.append(img.size[1])\n", + " \n", + " # 获得图像中心区域大小为size的图像块\n", + " cx, cy = (int(i/2) for i in img.size)\n", + " box = (cx-50, cy-50, cx+50, cy+50)\n", + " region = img.crop(box)\n", + " \n", + " # 计算选取图像块的标准差 分为红绿蓝三种\n", + " stat = ImageStat.Stat(region)\n", + " imgRrange.append(stat.extrema[0][1]-stat.extrema[0][0])\n", + " imgGrange.append(stat.extrema[1][1]-stat.extrema[1][0])\n", + " imgBrange.append(stat.extrema[2][1]-stat.extrema[2][0])\n", + " \n", + " newImgs.append(region)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "b5ad4f91", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 161 entries, 0 to 160\n", + "Data columns (total 9 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 0 161 non-null float64\n", + " 1 1 161 non-null float64\n", + " 2 2 161 non-null float64\n", + " 3 3 161 non-null float64\n", + " 4 4 161 non-null float64\n", + " 5 5 161 non-null float64\n", + " 6 6 161 non-null float64\n", + " 7 7 161 non-null float64\n", + " 8 8 161 non-null float64\n", + "dtypes: float64(9)\n", + "memory usage: 11.4 KB\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
012345678
0148.6041138.638164.36943.6259024.12549710.4859314.2424254.79891612.044228
1163.6788145.548754.45813.9233702.8350013.4789724.4394653.2399164.039823
2153.9485147.081071.95762.2087661.8033973.1154782.6237962.1392893.621357
3150.3755151.398564.31182.0151671.5140342.6989222.3446581.8090653.136727
4150.7380150.973864.62461.9029341.6580453.0980442.2422701.9520673.593836
\n", + "
" + ], + "text/plain": [ + " 0 1 2 3 4 5 6 \\\n", + "0 148.6041 138.6381 64.3694 3.625902 4.125497 10.485931 4.242425 \n", + "1 163.6788 145.5487 54.4581 3.923370 2.835001 3.478972 4.439465 \n", + "2 153.9485 147.0810 71.9576 2.208766 1.803397 3.115478 2.623796 \n", + "3 150.3755 151.3985 64.3118 2.015167 1.514034 2.698922 2.344658 \n", + "4 150.7380 150.9738 64.6246 1.902934 1.658045 3.098044 2.242270 \n", + "\n", + " 7 8 \n", + "0 4.798916 12.044228 \n", + "1 3.239916 4.039823 \n", + "2 2.139289 3.621357 \n", + "3 1.809065 3.136727 \n", + "4 1.952067 3.593836 " + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import pandas as pd\n", + "# 构建训练数据集和分类标签\n", + "data = []\n", + "dy = []\n", + "for i, img in enumerate(newImgs):\n", + " r, g, b = np.split(np.array(img), 3, axis = 2)\n", + " \n", + " #计算一阶矩\n", + " r_m1 = np.mean(r)\n", + " g_m1 = np.mean(g)\n", + " b_m1 = np.mean(b)\n", + " \n", + " #二阶矩\n", + " r_m2 = np.std(r)\n", + " g_m2 = np.std(g)\n", + " b_m2 = np.std(b)\n", + " \n", + " #三阶矩\n", + " r_m3 = np.mean(abs(r - r.mean())**3)**(1/3)\n", + " g_m3 = np.mean(abs(g - g.mean())**3)**(1/3)\n", + " b_m3 = np.mean(abs(b - b.mean())**3)**(1/3)\n", + " \n", + " # 构造新数据集\n", + " df = np.array([r_m1,g_m1,b_m1,r_m2,g_m2,b_m2,r_m3,g_m3,b_m3])\n", + " data.append(df)\n", + " \n", + " # 保存对应的分类标签\n", + " dy.append(int(imgFiles[i][0]))\n", + "\n", + "dy = np.array(dy)\n", + "data = pd.DataFrame(np.array(data))\n", + "data.info()\n", + "data.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "da56ab61", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "D:\\anaconda\\lib\\site-packages\\scipy\\__init__.py:146: UserWarning: A NumPy version >=1.16.5 and <1.23.0 is required for this version of SciPy (detected version 1.24.3\n", + " warnings.warn(f\"A NumPy version >={np_minversion} and <{np_maxversion}\"\n" + ] + }, + { + "data": { + "text/plain": [ + "((128, 9), (33, 9), (128,))" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from sklearn.model_selection import train_test_split\n", + "x_train,x_test,y_train,y_test=train_test_split(data,dy,test_size=0.2,random_state=0)\n", + "x_train.shape,x_test.shape,y_train.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "8c6be264", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0.7575757575757576\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "D:\\anaconda\\lib\\site-packages\\sklearn\\neural_network\\_multilayer_perceptron.py:692: ConvergenceWarning: Stochastic Optimizer: Maximum iterations (200) reached and the optimization hasn't converged yet.\n", + " warnings.warn(\n" + ] + } + ], + "source": [ + "from sklearn.metrics import accuracy_score\n", + "from sklearn.neural_network import MLPClassifier\n", + "mlp=MLPClassifier()\n", + "mlp.fit(x_train,y_train)\n", + "y_pred=mlp.predict(x_test)\n", + "print(accuracy_score(y_pred,y_test))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d7c33fc8", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.12" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}