电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

Python圖像識別+KNN求解數獨的實現

瀏覽:45日期:2022-07-05 16:06:07

Python-opencv+KNN求解數獨

最近一直在玩數獨,突發奇想實現圖像識別求解數獨,輸入到輸出平均需要0.5s。

整體思路大概就是識別出圖中數字生成list,然后求解。

輸入輸出demo

數獨采用的是微軟自帶的Microsoft sudoku軟件隨便截取的圖像,如下圖所示:

Python圖像識別+KNN求解數獨的實現

經過程序求解后,得到的結果如下圖所示:

Python圖像識別+KNN求解數獨的實現

程序具體流程

程序整體流程如下圖所示:

Python圖像識別+KNN求解數獨的實現

讀入圖像后,根據求解輪廓信息找到數字所在位置,以及不包含數字的空白位置,提取數字信息通過KNN識別,識別出數字;無數字信息的在list中置0;生成未求解數獨list,之后求解數獨,將信息在原圖中顯示出來。

# -*-coding:utf-8-*-import osimport cv2 as cvimport numpy as npimport time#####################################################尋找數字生成listdef find_dig_(img, train_set): if img is None: print('無效的圖片!') os._exit(0) return _, thre = cv.threshold(img, 230, 250, cv.THRESH_BINARY_INV) _, contours, hierarchy = cv.findContours(thre, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE) sudoku_list = [] boxes = [] for i in range(len(hierarchy[0])): if hierarchy[0][i][3] == 0: # 表示父輪廓為 0 boxes.append(hierarchy[0][i]) # 提取數字 nm = [] for j in range(len(boxes)): # 此處len(boxes)=81 if boxes[j][2] != -1: x, y, w, h = cv.boundingRect(contours[boxes[j][2]]) nm.append([x, y, w, h]) # 在原圖中框選各個數字 cropped = img[y:y + h, x:x + w] im = img_pre(cropped)#預處理 AF = incise(im)#切割數字圖像 result = identification(train_set, AF, 7)#knn識別 sudoku_list.insert(0, int(result))#生成list else: sudoku_list.insert(0, 0)if len(sudoku_list) == 81: sudoku_list= np.array(sudoku_list) sudoku_list= sudoku_list.reshape((9, 9)) print('old_sudoku -> n', sudoku_list) return sudoku_list, contours, hierarchy else: print('無效的圖片!') os._exit(0)#######################################################KNN算法識別數字def img_pre(cropped): # 預處理數字圖像 im = np.array(cropped) # 轉化為二維數組 for i in range(im.shape[0]): # 轉化為二值矩陣 for j in range(im.shape[1]): # print(im[i, j]) if im[i, j] != 255:im[i, j] = 1 else:im[i, j] = 0 return im# 提取圖片特征def feature(A): midx = int(A.shape[1] / 2) + 1 midy = int(A.shape[0] / 2) + 1 A1 = A[0:midy, 0:midx].mean() A2 = A[midy:A.shape[0], 0:midx].mean() A3 = A[0:midy, midx:A.shape[1]].mean() A4 = A[midy:A.shape[0], midx:A.shape[1]].mean() A5 = A.mean() AF = [A1, A2, A3, A4, A5] return AF# 切割圖片并返回每個子圖片特征def incise(im): # 豎直切割并返回切割的坐標 a = []; b = [] if any(im[:, 0] == 1): a.append(0) for i in range(im.shape[1] - 1): if all(im[:, i] == 0) and any(im[:, i + 1] == 1): a.append(i + 1) elif any(im[:, i] == 1) and all(im[:, i + 1] == 0): b.append(i + 1) if any(im[:, im.shape[1] - 1] == 1): b.append(im.shape[1]) # 水平切割并返回分割圖片特征 names = locals(); AF = [] for i in range(len(a)): names[’na%s’ % i] = im[:, range(a[i], b[i])] if any(names[’na%s’ % i][0, :] == 1): c = 0 else: for j in range(names[’na%s’ % i].shape[0]):if j < names[’na%s’ % i].shape[0] - 1: if all(names[’na%s’ % i][j, :] == 0) and any(names[’na%s’ % i][j + 1, :] == 1): c = j breakelse: c = j if any(names[’na%s’ % i][names[’na%s’ % i].shape[0] - 1, :] == 1): d = names[’na%s’ % i].shape[0] - 1 else: for j in range(names[’na%s’ % i].shape[0]):if j < names[’na%s’ % i].shape[0] - 1: if any(names[’na%s’ % i][j, :] == 1) and all(names[’na%s’ % i][j + 1, :] == 0): d = j + 1 breakelse: d = j names[’na%s’ % i] = names[’na%s’ % i][range(c, d), :] AF.append(feature(names[’na%s’ % i])) # 提取特征 for j in names[’na%s’ % i]: pass return AF# 訓練已知圖片的特征def training(): train_set = {} for i in range(9): value = [] for j in range(15): ima = cv.imread(’E:/test_image/knn_test/{}/{}.png’.format(i + 1, j + 1), 0) im = img_pre(ima) AF = incise(im) value.append(AF[0]) train_set[i + 1] = value return train_set# 計算兩向量的距離def distance(v1, v2): vector1 = np.array(v1) vector2 = np.array(v2) Vector = (vector1 - vector2) ** 2 distance = Vector.sum() ** 0.5 return distance# 用最近鄰算法識別單個數字def knn(train_set, V, k): key_sort = [11] * k value_sort = [11] * k for key in range(1, 10): for value in train_set[key]: d = distance(V, value) for i in range(k):if d < value_sort[i]: for j in range(k - 2, i - 1, -1): key_sort[j + 1] = key_sort[j] value_sort[j + 1] = value_sort[j] key_sort[i] = key value_sort[i] = d break max_key_count = -1 key_set = set(key_sort) for key in key_set: if max_key_count < key_sort.count(key): max_key_count = key_sort.count(key) max_key = key return max_key# 生成數字def identification(train_set, AF, k): result = ’’ for i in AF: key = knn(train_set, i, k) result = result + str(key) return result#############################################################################################################求解數獨def get_next(m, x, y): # 獲得下一個空白格在數獨中的坐標。 :param m 數獨矩陣 :param x 空白格行數 :param y 空白格列數 ''' for next_y in range(y + 1, 9): # 下一個空白格和當前格在一行的情況 if m[x][next_y] == 0: return x, next_y for next_x in range(x + 1, 9): # 下一個空白格和當前格不在一行的情況 for next_y in range(0, 9): if m[next_x][next_y] == 0:return next_x, next_y return -1, -1 # 若不存在下一個空白格,則返回 -1,-1def value(m, x, y): # 返回符合'每個橫排和豎排以及九宮格內無相同數字'這個條件的有效值。 i, j = x // 3, y // 3 grid = [m[i * 3 + r][j * 3 + c] for r in range(3) for c in range(3)] v = set([x for x in range(1, 10)]) - set(grid) - set(m[x]) - set(list(zip(*m))[y]) return list(v)def start_pos(m): # 返回第一個空白格的位置坐標 for x in range(9): for y in range(9): if m[x][y] == 0:return x, y return False, False # 若數獨已完成,則返回 False, Falsedef try_sudoku(m, x, y): # 試著填寫數獨 for v in value(m, x, y): m[x][y] = v next_x, next_y = get_next(m, x, y) if next_y == -1: # 如果無下一個空白格 return True else: end = try_sudoku(m, next_x, next_y) # 遞歸 if end:return True m[x][y] = 0 # 在遞歸的過程中,如果數獨沒有解開, # 則回溯到上一個空白格def sudoku_so(m): x, y = start_pos(m) try_sudoku(m, x, y) print('new_sudoku -> n', m) return m#################################################### 將結果繪制到原圖def draw_answer(img, contours, hierarchy, new_sudoku_list ): new_sudoku_list = new_sudoku_list .flatten().tolist() for i in range(len(contours)): cnt = contours[i] if hierarchy[0, i, -1] == 0: num = new_soduku_list.pop(-1) if hierarchy[0, i, 2] == -1:x, y, w, h = cv.boundingRect(cnt)cv.putText(img, '%d' % num, (x + 19, y + 56), cv.FONT_HERSHEY_SIMPLEX, 1.8, (0, 0, 255), 2) # 填寫數字 cv.imwrite('E:/answer.png', img)if __name__ == ’__main__’: t1 = time.time() train_set = training() img = cv.imread(’E:/test_image/python_test_img/Sudoku.png’) img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY) sudoku_list, contours, hierarchy = find_dig_(img_gray, train_set) new_sudoku_list = sudoku_so(sudoku_list) draw_answer(img, contours, hierarchy, new_sudoku_list ) print('time :',time.time()-t1)

PS:

使用KNN算法需要創建訓練集,數獨中共涉及9個數字,“1,2,3,4,5,6,7,8,9”各15幅圖放入文件夾中,如下圖所示。

Python圖像識別+KNN求解數獨的實現

到此這篇關于Python圖像識別+KNN求解數獨的實現的文章就介紹到這了,更多相關Python KNN求解數獨內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Python 編程
相關文章:
主站蜘蛛池模板: 闪蒸干燥机-喷雾干燥机-带式干燥机-桨叶干燥机-[常州佳一干燥设备] | 碳化硅,氮化硅,冰晶石,绢云母,氟化铝,白刚玉,棕刚玉,石墨,铝粉,铁粉,金属硅粉,金属铝粉,氧化铝粉,硅微粉,蓝晶石,红柱石,莫来石,粉煤灰,三聚磷酸钠,六偏磷酸钠,硫酸镁-皓泉新材料 | 水性漆|墙面漆|木器家具漆|水漆涂料_晨阳水漆官网 | 哈尔滨京科脑康神经内科医院-哈尔滨治疗头痛医院-哈尔滨治疗癫痫康复医院 | 色谱柱-淋洗液罐-巴罗克试剂槽-巴氏吸管-5ml样品瓶-SBS液氮冻存管-上海希言科学仪器有限公司 | 工业洗衣机_工业洗涤设备_上海力净工业洗衣机厂家-洗涤设备首页 bkzzy在职研究生网 - 在职研究生招生信息咨询平台 | 环境模拟实验室_液体-气体控温机_气体控温箱_无锡双润冷却科技有限公司 | 「银杏树」银杏树行情价格_银杏树种植_山东程锦园林 | 防爆电机_防爆电机型号_河南省南洋防爆电机有限公司 | 皮带机-带式输送机价格-固定式胶带机生产厂家-河南坤威机械 | 扬尘在线监测系统_工地噪声扬尘检测仪_扬尘监测系统_贝塔射线扬尘监测设备「风途物联网科技」 | 邢台人才网_邢台招聘网_邢台123招聘【智达人才网】 | 温州在线网| 中空玻璃生产线,玻璃加工设备,全自动封胶线,铝条折弯机,双组份打胶机,丁基胶/卧式/立式全自动涂布机,玻璃设备-山东昌盛数控设备有限公司 | 欧版反击式破碎机-欧版反击破-矿山石料破碎生产线-青州奥凯诺机械 | 退火炉,燃气退火炉,燃气热处理炉生产厂家-丹阳市丰泰工业炉有限公司 | 青岛美佳乐清洁工程有限公司|青岛油烟管道清洗|酒店|企事业单位|学校工厂厨房|青岛油烟管道清洗 插针变压器-家用电器变压器-工业空调变压器-CD型电抗器-余姚市中驰电器有限公司 | 泉州陶瓷pc砖_园林景观砖厂家_石英砖地铺石价格 _福建暴风石英砖 | 茶楼装修设计_茶馆室内设计效果图_云臻轩茶楼装饰公司 | 苏州注册公司_苏州代理记账_苏州工商注册_苏州代办公司-恒佳财税 | 深圳货架厂_仓库货架公司_重型仓储货架_线棒货架批发-深圳市诺普泰仓储设备有限公司 | 紫外线老化试验箱_uv紫外线老化试验箱价格|型号|厂家-正航仪器设备 | 世界箱包品牌十大排名,女包小众轻奢品牌推荐200元左右,男包十大奢侈品牌排行榜双肩,学生拉杆箱什么品牌好质量好 - Gouwu3.com | 超声波清洗机_大型超声波清洗机_工业超声波清洗设备-洁盟清洗设备 | 扒渣机厂家_扒渣机价格_矿用扒渣机_铣挖机_撬毛台车_襄阳永力通扒渣机公司 | ★店家乐|服装销售管理软件|服装店收银系统|内衣店鞋店进销存软件|连锁店管理软件|收银软件手机版|会员管理系统-手机版,云版,App | 西门子伺服电机维修,西门子电源模块维修,西门子驱动模块维修-上海渠利 | 无锡网站建设_企业网站定制-网站制作公司-阿凡达网络 | SDG吸附剂,SDG酸气吸附剂,干式酸性气体吸收剂生产厂家,超过20年生产使用经验。 - 富莱尔环保设备公司(原名天津市武清县环保设备厂) | 济南玻璃安装_济南玻璃门_济南感应门_济南玻璃隔断_济南玻璃门维修_济南镜片安装_济南肯德基门_济南高隔间-济南凯轩鹏宇玻璃有限公司 | 撕碎机_轮胎破碎机_粉碎机_回收生产线厂家_东莞华达机械有限公司 | 立式_复合式_壁挂式智能化电伴热洗眼器-上海达傲洗眼器生产厂家 理化生实验室设备,吊装实验室设备,顶装实验室设备,实验室成套设备厂家,校园功能室设备,智慧书法教室方案 - 东莞市惠森教学设备有限公司 | 一氧化氮泄露报警器,二甲苯浓度超标报警器-郑州汇瑞埔电子技术有限公司 | 丹佛斯变频器-Danfoss战略代理经销商-上海津信变频器有限公司 | 炭黑吸油计_测试仪,单颗粒子硬度仪_ASTM标准炭黑自销-上海贺纳斯仪器仪表有限公司(HITEC中国办事处) | 常州减速机_减速机厂家_常州市减速机厂有限公司 | 分光色差仪,测色仪,反透射灯箱,爱色丽分光光度仪,美能达色差仪维修_苏州欣美和仪器有限公司 | 耐磨焊丝,堆焊焊丝,耐磨药芯焊丝,碳化钨焊丝-北京耐默公司 | 空气能采暖,热泵烘干机,空气源热水机组|设备|厂家,东莞高温热泵_正旭新能源 | 氮化镓芯片-碳化硅二极管 - 华燊泰半导体 | 电镀标牌_电铸标牌_金属标贴_不锈钢标牌厂家_深圳市宝利丰精密科技有限公司 |