其他分享
首页 > 其他分享> > 化学结构式图像识别

化学结构式图像识别

作者:互联网

关于个人项目进行化学图像识别的说明

  1. 原理说明:首先通过百度的ocr进行化学式的文字识别以及其坐标,进而实现官能团的识别以及位置构建
  2. 对全图进行扫描, 进而完整确定全图的结构。
  3. 将来可以引入ai,更高效便利实现图像识别
# coding=utf-8
from PIL import Image
from math import *
from aip import AipOcr
AppID = "25350322"
APIkey = "5tZwU0OWjz4ZOrhxLQWC6gvn"
SecretID = "AXloqKsHPGpXoNHGk5i8DxvrwVUIGT6D"
aipOcr = AipOcr(AppID, APIkey, SecretID)
def zhuaqu(filePath):
#filePath = "D:\\bf.jpg"
   def get_file_content(filePath):
       with open(filePath, 'rb') as fp:
           return fp.read()    
   options = {
       'detect_direction': 'true',
       'language_type': 'CHN_ENG',
   }

   result = aipOcr.accurate(get_file_content(filePath), options)
   return result["words_result"]
   # print(result)
   # words_result=result['words_result']
   # for i in range(len(words_result)):
   #     print(words_result[i]['words'])

这是我利用百度ocr提供的文字识别代码写出的调用函数
接下来是化学式描图的主程序
这里描图的过程可以说是在一团毛线中找“线头”,当找到一个键线式的“线头”,那么接下来的工作就简单了:顺着这个线头向前即可。

from time import sleep
from PIL import Image
import numpy as np
import math
from huaxue1215 import zhuaqu
#定义区
Col = [(255, 0, 0), (0, 255, 0), (0, 0, 255), (255, 255, 0), (255, 0, 255), (0, 255, 255)]
pa = "D:\\化学俱乐部项目\\yangli2_NO23.jpg"
P = Image.open(pa)
Points = []
Used=np.zeros((max(P.height, P.width), max(P.height, P.width)))
#
def checktext(Tr, x, y): #判断像素是否在文字范围内
    for i in Tr:
        if (x >= i["location"]["left"]) and (x <= (i["location"]["left"] + i["location"]["width"])) and(y >= i["location"]["top"]) and (y <= (i["location"]["top"] + i["location"]["height"])):
            return True
    return False
#Zuobiao = [[1, 0], [-1, 0], [1, sqrt(3)], [-1, sqrt(3)]]
Lines = []
def Findnear(Po):#查找格子周围的点,R为半径
    Ret = []
    R = 5
    for Y in range(Po[1]-R, Po[1]+R + 1):
        if check(P.getpixel((Po[0] - R, Y))):
            if Used[Po[0] - R, Y] != 1:
                Ret.append((Po[0] - R, Y))
        if check(P.getpixel((Po[0] + R, Y))):
            if Used[Po[0] + R, Y] != 1:
                Ret.append((Po[0] + R, Y))
    for X in range(Po[0] - R + 1, Po[0] + R):
        if check(P.getpixel((X, Po[1] - R))):
            if Used[X, Po[1] - R] != 1:
                Ret.append((X, Po[1] - R))
        if check(P.getpixel((X, Po[1] + R))):
            if Used[X, Po[1] + R] != 1:
                Ret.append((X, Po[1] + R))
    return Ret
    
#测试用
def dot(Mp, x, y, col):
    for i in range(x - 2, x + 2):
        for j in range(y - 2, y + 2):
            Mp.putpixel((i, j), col)

Q = P#Image.new("RGB", (P.height, P.width), (255, 255, 255))

def check(x):
    return ((x[0] < 128) & (x[1] < 128) & (x[2] < 128)) == True
#黑点
for i in range(P.width):
    for j in range(P.height):
        Point = P.getpixel((i, j))
        if check(Point):
            Points.append((i, j)) #抓取所有黑色像素,描边
        #    Q.putpixel((i, j), (0, 0, 0))

# print(Used)
# print(Points)
# Q.show()
T = zhuaqu(pa)
# print(T)
Tx = T[0]["location"]["left"] + T[0]["location"]["width"]
Ty = T[0]["location"]["top"] + T[0]["location"]["height"]
for i in T:
    for X in range(i["location"]["left"], i["location"]["left"] + i["location"]["width"]):
        for Y in range(i["location"]["top"], i["location"]["top"] + i["location"]["height"]):
            Used[X, Y] = 1
# with open(r"D:/1.txt", "w") as Wrt:
#     for p in Used:
#         for q in p:
#             Wrt.write(str(q) + ",")
#         Wrt.write("\n")
#从一处文字开始入手
# print("文字坐标:",Tx, Ty)
# dot(Tx, Ty, (0, 0, 255))
Points = sorted(Points, key=lambda x:((x[0] - Tx) ** 2 + (x[1] - Ty) ** 2) + 10 ** 8 * checktext(T, x[0], x[1]))
#print(Points)
# for i in Points:
#     if checktext(T, i[0], i[1]) != True:
#         dot(i[0], i[1], (255, 0, 0))
Nowx, Nowy = Points[0][0], Points[0][1]
# Startx, Starty = Nowx, Nowy
# print(Nowx, Nowy)
# dot(Nowx, Nowy, (0, 255, 0))
# dot(Points[10][0], Points[10][1], (0, 255, 0))
# Q.save("new.bmp")
# Q.show()
# dx = abs(Points[1][0] - Points[0][0])
# dy = abs(Points[1][1] - Points[0][1])
Linex = []
Liney = []
# print(dx, dy)
# while Points.count((Nowx, Nowy)):
#     Used[Nowx, Nowy] = 1
#     Linex.append(Nowx)
#     Liney.append(Nowy)
#     Nowx += dx
#     Nowy += dy
# Linex.append(Nowx)
# Liney.append(Nowy)
# print(Linex, Liney)
# Lines.append([Linex, Liney])
# Linex.clear()
# Liney.clear()

while True:
    Used[Nowx, Nowy] = 1
    k = Findnear((Nowx, Nowy))
    if len(k) == 0:
        break
    dx = k[0][0] - Nowx
    dy = k[0][1] - Nowy
    # print("---------------", dx, dy)
    Pnow = k[0]
    Used[Pnow[0], Pnow[1]] = 1
    Linex.append(Pnow[0])
    Liney.append(Pnow[1])
#    print(Findnear((367,79), 3))
#    sleep(3)
    while True:
        flag = False
        # if (Used[Pnow[0] + dx, Pnow[1] + dy] != 1) & (Points.count((Pnow[0] - dx, Pnow[1] - dy)) != 0):
        #     Used[Pnow[0] + dx, Pnow[1] + dy] = 1
        #     Q.putpixel((Pnow[0] + dx, Pnow[1] + dy), Col[0])
        #     Linex.append(Pnow[0] + dx)
        #     Liney.append(Pnow[1] + dy)
        #     Pnow = (Pnow[0] + dx, Pnow[1] + dy)
        #     continue
        for tmp in Findnear((Pnow[0], Pnow[1])):
            Tan1 = (tmp[0] - Pnow[0]) * dy - (tmp[1] - Pnow[1]) * dx
            Tan2 = (1 + (tmp[0] - Pnow[0]) * dx)
            if Tan1 * Tan2 > 0:
                F1 = (Tan1 <= Tan2 * math.sqrt(1/3))
            else:
                F1 = (Tan1 * -1 <= Tan2 * math.sqrt(1/3))
            if F1 and (Used[tmp[0], tmp[1]] == 0):
                Used[tmp[0], tmp[1]] = 1
                Q.putpixel((tmp[0], tmp[1]), Col[0])
                Linex.append(tmp[0])
                Liney.append(tmp[1])
            #    print(tmp)
                Pnow = tmp
                flag = True
                break
        # print("break1!")
        if flag == False:
            break
    Nowx, Nowy = Linex[-1], Liney[-1]
    Lines.append((Linex, Liney))
    print(Lines)
    Linex.clear()
    Liney.clear()
with open("D:/化学俱乐部项目/Lines.txt", "w") as f:
    f.write(str(len(Lines)))

Q.show()

描图结果如图所示

标签:图像识别,化学,filePath,result,words,import,结构式,255
来源: https://blog.csdn.net/jzh666666/article/details/122210452