如何使用OpenCV增加图像DPI?

21

在使用 opencv 中的 ocr 读取之前,我需要增加图像的 DPI。问题是:

  1. 我不知道现在图片的 DPI
  2. 我不知道如何增加图片的 DPI

我在谷歌上搜索了一下,几乎每个答案都建议使用 cv2.resize

image = cv2.imread("source.png")
resized_image = cv2.resize(image, (100, 50)) #I need to change it to 300 DPI

resize只会改变图像大小,但并不会增加dpi。我已经尝试使用它并在Photoshop中进行了检查,发现dpi没有改变。

如何使用opencv来实现?

我需要将dpi更改为300,为什么需要知道当前的dpi值呢?因为如果已经有dpi > 300,那我就不需要转换它。

我是用Python实现的。


可能是在OpenCV中更改图像的dpi的重复问题。 - Sraw
3个回答

7

dpi只是JPEG/TIFF/PNG文件头中的一个数字。在打印图像之前,它完全与世界和人们无关,并决定了图像以像素为单位的尺寸大小。

在图像处理期间,dpi没有任何意义。唯一感兴趣的是你拥有的像素数量。这是图像质量或信息内容的最终决定因素,不论你想如何描述它。

我不认为你可以使用OpenCV设置它。你可以在终端中使用ImageMagick这样设置:

mogrify -set density 300 *.png           # v6 ImageMagick
magick mogrify -set density 300 *.png    # v7 ImageMagick

您可以使用以下方法进行检查:
identify -format "Density: %x x %y" SomeImage.jpg    # v6 ImageMagick
magick identify -format ... as above                 # v7 ImageMagick

您可以使用终端中的exiftool执行类似的操作 - 请注意,exiftoolImageMagick更小,更易于维护,因为它只是一个(非常强大)的Perl脚本:

从EXIF IFD1信息中提取图像分辨率:

exiftool -IFD1:XResolution -IFD1:YResolution image.jpg

从图像中提取所有标签名称包含“Resolution”单词的标签:
exiftool '-*resolution*' image.jpg

设置image.jpg的X/Y分辨率(密度):

exiftool -xresolution=300 -yresolution=300 image.jpg

以下是我在答案开头所说的示例...

使用 ImageMagick 创建一张大小为 1024x768,没有 dpi 信息的图片:

convert -size 1024x768 xc:black image.jpg

现在来看一下:

identify -verbose image.jpg

Image: image.jpg
  Format: JPEG (Joint Photographic Experts Group JFIF format)
  Mime type: image/jpeg
  Class: PseudoClass
  Geometry: 1024x768+0+0
  Units: Undefined
  Colorspace: Gray
  Type: Bilevel
  ...
  ...

现在更改dpi并设置dpi单位,然后再次检查:

mogrify -set density 300 -units pixelsperinch image.jpg   # Change dpi

identify -verbose image.jpg                               # Examine

Image: image.jpg
  Format: JPEG (Joint Photographic Experts Group JFIF format)
  Mime type: image/jpeg
  Class: PseudoClass
  Geometry: 1024x768+0+0            <--- Number of pixels is unchanged
  Resolution: 300x300               <---
  Print size: 3.41333x2.56          <--- Print size is now known
  Units: PixelsPerInch              <---
  Colorspace: Gray
  Type: Bilevel
  ...
  ...

现在你可以看到,我们突然知道打印出来的图片有多大,而像素数量并没有改变。


当然,你可以在Python中使用system(),在处理和保存图像后使用mogrify -set density 300 XYZ.png。也许还有其他的Python库——我正在检查——比如更自然的使用exiv2 - Mark Setchell
我没有使用过Python绑定,但也许可以尝试使用exiv2 https://python3-exiv2.readthedocs.io/en/latest/tutorial.html?highlight=resolution - Mark Setchell
7
“在你打印这张图片之前,它对世界和他的狗都毫无意义。”- 你开玩笑吧?试着在电脑显示器和电影屏幕前看同一张图片,希望你能发现区别。DPI 对于每一个图形设备都很重要,包括屏幕。” - Agnius Vasiliauskas
谢谢您的帮助,但我需要在不调用图像文件的情况下处理它,因此在cv2.imread("image.png")之后,我可以在代码或内存中更改分辨率而无需保存。如果需要执行图像文件,则mogrify -set density 300 XYZ.png不能使用opencv图像数据。 - yozawiratama
请展示您的代码 - 具体来说,您是如何/在哪里将OpenCV中的图像传递给您正在使用的OCR代码的?您是否调用了imencode()或其他使您的OpenCV Mat成为OCR图像的函数?如果是这样,也许您可以将其编码为不包含dpi的NetPBM / PPM / PNM格式,因为它无法检查,所以您的OCR可能会更加满意。;-) - Mark Setchell
显示剩余6条评论

3

4
您提供的链接文章明确指出:“无论dpi或点大小,OCR错误率最强烈地与大写字母的像素高度相关。”,并且“传递给 Tesseract 的 PIX 结构中的 xres 和 yres 值几乎没有影响”...从而确认DPI不重要,只要字符的高度约为30个像素-无论dpi如何。 - Mark Setchell
我正在使用CV2对图像进行OCR预处理,需要以某种方式转换图像的有效DPI。如果我有一张纸上有一个1/4英寸大小的大写字母,并在200DPI的扫描仪上扫描它 - 我将得到50个像素的大写字母。我需要更改图像,使我获得字母的最大30像素。因此,当我们说我们想要更改图像中的DPI时,我们实际上是说我们想要按百分比减少像素数量,以使我们的OCR更好。那么我们如何使用CV2做到这一点呢? - Doug Bower

-2

DPI是图形设备(显示器、扫描仪、相机等)的继承属性。例如,假设我们正在扫描图像,想获得更好质量的图像,那么我们就设置扫描选项中更高的DPI值。如果没有更好的DPI选项,则需要购买支持更多扫描分辨率的更好扫描仪。有些设备/方法可以实现100 000 DPI


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接