<p><strong>基本步骤</strong>作为@Miki</p>
<blockquote>
<ol>
<li>read the source</li>
<li>threshed </li>
<li>find minAreaRect </li>
<li>warp by the rotated matrix </li>
<li>find and draw upper and lower bounds</li>
</ol>
</blockquote>
<p><a href="https://i.stack.imgur.com/WrJso.png" rel="noreferrer"><img src="https://i.stack.imgur.com/WrJso.png" alt="enter image description here"/></a></p>
<hr/>
<p>而Python中的代码:</p>
<pre><code>#!/usr/bin/python3
# 2018.01.16 01:11:49 CST
# 2018.01.16 01:55:01 CST
import cv2
import numpy as np
## (1) read
img = cv2.imread("img02.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
## (2) threshold
th, threshed = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY_INV|cv2.THRESH_OTSU)
## (3) minAreaRect on the nozeros
pts = cv2.findNonZero(threshed)
ret = cv2.minAreaRect(pts)
(cx,cy), (w,h), ang = ret
if w>h:
w,h = h,w
ang += 90
## (4) Find rotated matrix, do rotation
M = cv2.getRotationMatrix2D((cx,cy), ang, 1.0)
rotated = cv2.warpAffine(threshed, M, (img.shape[1], img.shape[0]))
## (5) find and draw the upper and lower boundary of each lines
hist = cv2.reduce(rotated,1, cv2.REDUCE_AVG).reshape(-1)
th = 2
H,W = img.shape[:2]
uppers = [y for y in range(H-1) if hist[y]<=th and hist[y+1]>th]
lowers = [y for y in range(H-1) if hist[y]>th and hist[y+1]<=th]
rotated = cv2.cvtColor(rotated, cv2.COLOR_GRAY2BGR)
for y in uppers:
cv2.line(rotated, (0,y), (W, y), (255,0,0), 1)
for y in lowers:
cv2.line(rotated, (0,y), (W, y), (0,255,0), 1)
cv2.imwrite("result.png", rotated)
</code></pre>
<hr/>
<p><strong>最终结果</strong>:</p>
<p><a href="https://i.stack.imgur.com/aym5D.png" rel="noreferrer"><img src="https://i.stack.imgur.com/aym5D.png" alt="enter image description here"/></a></p>