Python高手请来挑战一下吧

jmx_7247 2010-09-23 09:33:03
题目不难,但是不知道怎么做比较有效率,希望高手指点一下:

要求很简单,识别数字的区域即可,记录这些区域,然后方便在上面贴图,并改掉数字。


难点: 颜色一样,并且在同一排,一张图中有多个相同颜色的数字。

提示: 图片没有杂色点,用纯色即可匹配颜色

示例图片



...全文
327 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
pythonAihaozhe 2010-09-26
  • 打赏
  • 举报
回复
我写了第二个替换数字的,第一个实在不懂,高手配合一下了,真的很感谢你们。

# -*- coding: utf-8 -*-
import Image
import ImageFont
import ImageDraw

def replaceNumbers(im, identifiedRegions, replacingContents):
box = []
draw = ImageDraw.Draw(im)

for k,v in identifiedRegions.iteritems():
replaceNumber = replacingContents[k]
print k,v
for box in v:
print box
height = box[3] - box[1]
font = ImageFont.truetype('c:/windows/fonts/arial.ttf', height)
im.paste('white', box)
txt = replacingContents[k]
draw.text((box[0], box[1]), txt, font=font, fill='blue')
return im


if __name__ == '__main__':
regions = {'a':[(20,30,60,50),(90,130,100,130)],
'b':[(200,200,250,250)]}
contents = {'a':33, 'b':30}

im = Image.open("d:\\testpngs\\sample1.png")
newim = replaceNumbers(im, regions, contents)
newim.save("d:\\testpngs\\result5.png")
jmx_7247 2010-09-26
  • 打赏
  • 举报
回复
修改下两个function的参数

第一个
分析图像
输入:im obj, 文字颜色,
输出:一个字典 {'a':[(box1),(box2)], 'b':[(box1)]} box就是一般的box包含四个点的坐标(x1,y1,x2,y2)
如果有一个box那就一个box,如果有更多,在list里面放入更多的box

a是黄色(255,255,0),b是紫色
第二个
替换图像
输入:im obj,第一个function的输出结果,要替换内容的字典{'a':23,'b':21}永远是这样的格式!
只要key相同,替换的内容就是那个。
输出:new im obj
jmx_7247 2010-09-26
  • 打赏
  • 举报
回复
agile_su代码里面的tmp.txt是什么?
jmx_7247 2010-09-26
  • 打赏
  • 举报
回复
可以不可以稍微分开一点点?

我现在有一个这样的需求:

有两个function,
第一个function - 分析图片
输入一个image object, text colour的字典(格式{'a':"yellow", 'b':"another color"})
输出的是有文字区域的dictionary{'a':[(10,10),200,30]}tuple里面是左上角的位置,后面两个数字是长和宽

第二个function - 替换数字
输入的第一个function的输出结果,也就是那个dictionary;image object, 要替换的数字内容的字典比如{'a':23,'b':35}

十分感谢大家的帮忙,以后一定多多回报CSDN!
jmx_7247 2010-09-26
  • 打赏
  • 举报
回复
我对angel_su佩服的五体投地~~

一定好好学习! 目前我虽然接触python1周的时间,但是相信有众多CSDN网友的帮助,我一定能进步如飞。
angel_su 2010-09-26
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 notax 的回复:]

现在有一个pytesser 的包, http://code.google.com/p/pytesser/

[/Quote]
好像也是popen调度exe,仅输出所有识别文字,没能makebox(输出单char+坐标范围),这样后头没法做置换工作...
angel_su 2010-09-26
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 jmx_7247 的回复:]

agile_su代码里面的tmp.txt是什么?
[/Quote]
tesseract的输出,如果跑了我的范例脚本,做完文件没杀掉可以打开看看...
angel_su 2010-09-26
  • 打赏
  • 举报
回复
额外写个包装函数就成,颜色tuple可以当key,value不管几个统一用list,这样单纯些...

...
contents = {(255,255,0):[33], (128, 0, 128):[30]}
regions = getRegions(im,contents.keys())
....

def getRegions(im,clrs)
regions = {}
for clr in clrs:
regions[clr] = findbbox(im, clr)
return regions
jmx_7247 2010-09-26
  • 打赏
  • 举报
回复
第一个分析图片的输出能不能整理成这个样子呢?

Format is {'a':[(box1),(box2),(box3)],
'b':[(box1),(box2)]
'c':[(box1)]
}

a是黄色,b是紫色,c是其他颜色,一次类推,这些颜色的代码可以从参数中得到。
notax 2010-09-26
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 angel_su 的回复:]

也可试试用现成ocr软件做,譬如tesseract,用命令行调度下也很简单,底下写的代码主要仅是处理tesseract的输出,把它转换成配套的数据。
Python code
import Image
import ImageDraw
import subprocess

def findbbox(im, sel):
text = tesseract(im)

# te……
[/Quote]

楼上的不错哦,现在有一个pytesser 的包, http://code.google.com/p/pytesser/
不过我没用过
angel_su 2010-09-25
  • 打赏
  • 举报
回复
也可试试用现成ocr软件做,譬如tesseract,用命令行调度下也很简单,底下写的代码主要仅是处理tesseract的输出,把它转换成配套的数据。
import Image
import ImageDraw
import subprocess

def findbbox(im, sel):
text = tesseract(im)

# tesseract输出是按单字符和其坐标,转化成所需字串范围
word = ''.join([i[0] for i in text])
start = 0
boxes = []
for s in sel:
pos = word.find(s, start)
if pos == -1: continue
lx, ly = [], []
for i in range(len(s)):
data = text[pos+i].split()
lx.append(int(data[1]))
ly.append(int(data[2]))
lx.append(int(data[3]))
ly.append(int(data[4]))
# pil坐标原点在左上角, tesseract在左下角
box = (min(lx), im.size[1]-max(ly),
max(lx), im.size[1]-min(ly))
boxes.append(box)
start = pos + len(s)
return boxes

def tesseract(im):
# 图像另存为tesseract基本支持的uncompressed tiff
# 本例自行处理成黑白能完全识别,其它按情况不一...
mono = im.convert('L').point(lambda i: i > 245 and 255)
mono.save('tmp.tif', 'TIFF')

# tesseract命令行参数:
cmd = 'tesseract tmp.tif tmp batch.nochop makebox'
p = subprocess.Popen(cmd)
p.wait()
with open('tmp.txt') as f:
return f.readlines()


if __name__ == '__main__':
im = Image.open('sample1.png')
im.load()
draw = ImageDraw.Draw(im)
# 选定图片里的字,必须按顺序从左至右,由上而下
sel = ['60', '11cm', '60', '60']
for box in findbbox(im, sel):
draw.rectangle(box, outline='red')
im.save('makebox.png')
im.show()

jmx_7247 2010-09-24
  • 打赏
  • 举报
回复
感谢angel_su的帮助,但是我能力有限,完全不懂~~
angel_su 2010-09-24
  • 打赏
  • 举报
回复
嗯,按上思路实现了下,供参考...
# -*- coding: utf-8 -*-
import Image
import ImageFilter
import ImageFont
import ImageDraw

def findbbox(im, clr, ix=36, iy=12, ec=16, eb=3):
"""
im: obj of image
clr: color of text
iy: increment when scanning in y-dir
ix: increment when scanning in x-dir
ec: tolerance of color
eb: tolerance of bbox

return a list of bbox
"""
#分层做mask,叠加后取文字范围
mask = None
for band, c in zip(im.split(), clr):
band = band.point(lambda i: i <= c+ec and i >= c-ec and 255)
if mask is None:
mask = band
else:
mask.paste(band, mask=mask)
mbox = mask.getbbox()
if mbox is None: return

#对文字范围先yscan取单行范围,再xscan取单词范围
boxes = []
for box in yscan(mask.crop(mbox), iy):
ox, oy = mbox[0], mbox[1]
ybox = (ox+box[0], oy+box[1], ox+box[2], oy+box[3])
for box in xscan(mask.crop(ybox), ix):
ox, oy = ybox[0], ybox[1]
xbox = (ox+box[0]-eb, oy+box[1]-eb,
ox+box[2]+eb, oy+box[3]+eb)
boxes.append(xbox)
#im.crop(xbox).show()
return boxes


def yscan(im, incr):
oy, prev = 0, None
for y in range(0, im.size[1]+incr*2, incr):
curr = im.crop((0, oy, im.size[0], y)).getbbox()
if curr and curr == prev:
yield curr[0], curr[1]+oy, curr[2], curr[3]+oy
curr = None
if curr is None:
oy = y
prev = curr


def xscan(im, incr):
ox, prev = 0, None
for x in range(0, im.size[0]+incr*2, incr):
curr = im.crop((ox, 0, x, im.size[1])).getbbox()
if curr and curr == prev:
yield curr[0]+ox, curr[1], curr[2]+ox, curr[3]
curr = None
if curr is None:
ox = x
prev = curr

if __name__ == '__main__':
files = ['sample1.png', 'sample2.png']
for fname in files:
im = Image.open(fname)
im = im.filter(ImageFilter.MedianFilter)
boxes = findbbox(im, (255, 255, 0))
boxes += findbbox(im, (128, 0, 128))

txt = ['50\xb0', '65\xb0', '65\xb0', '100cm']
clr = ['red', 'green', 'cyan', 'blue']
height = max([box[3]-box[1] for box in boxes])
font = ImageFont.truetype('c:/windows/fonts/msyhbd.ttf', height)
draw = ImageDraw.Draw(im)
for i, box in enumerate(boxes):
im.paste('white', box)
draw.text((box[0], box[1]), txt[i], font=font, fill=clr[i])
im.show()

angel_su 2010-09-23
  • 打赏
  • 举报
回复
可以照我上次一个字处理的方式变化一下,按一图取黄色得将到3组字的范围,继续切割处理譬如先从上间隔合适的点数递增往下扫描文字范围,当文字范围没变化就可以当找到一行字,然后对这行字用同样手法往水平方向做便可以取到单词...
javacode007 2010-09-23
  • 打赏
  • 举报
回复
先占个沙发啊
内容概要:本文围绕“新型电力系统下多分布式电源接入配电网承载力评估方法”的研究,系统性地介绍了基于Matlab的仿真建模与代码实现方案,旨在评估高比例分布式电源(如光伏、风电等)接入背景下配电网的接纳能力。研究融合了智能优化算法(如蜣螂优化、灰狼优化、遗传算法)、多目标优化、鲁棒优化及双层优化模型,结合潮流计算、稳定性分析与故障仿真,构建了完整的承载力评估体系。文档不仅提供核心算法实现,还拓展至微电网调度、储能配置、电氢耦合系统、电动汽车协同等前沿方向,强调“复现+创新”相结合的科研路径,助力研究者快速掌握高水平论文复现技巧并激发原创思路。; 适合人群:具备电力系统、自动化或相关专业背景,熟悉Matlab/Simulink仿真环境,正在从事科研或工程应用的研究生及初级科研人员(工作1-3年);; 使用场景及目标:①复现高水平期刊中关于配电网承载力的优化模型;②开展高比例可再生能源接入下的配电网规划与运行研究;③学习并应用智能优化算法解决复杂电力系统问题;④获取完整科研资源包以加速课题进展与论文撰写; 阅读建议:建议读者关注公众号“荔枝科研社”获取网盘资源,下载全套代码与模型文件,按照文档结构循序渐进学习,重点理解算法设计逻辑与仿真建模细节,结合所提供的复现案例深化对优化模型与工程应用场景的理解,提升科研效率与创新能力。

37,738

社区成员

发帖
与我相关
我的任务
社区描述
JavaScript,VBScript,AngleScript,ActionScript,Shell,Perl,Ruby,Lua,Tcl,Scala,MaxScript 等脚本语言交流。
社区管理员
  • 脚本语言(Perl/Python)社区
  • WuKongSecurity@BOB
加入社区
  • 近7日
  • 近30日
  • 至今

试试用AI创作助手写篇文章吧