Here’s a modified implementation of the Projection Profile Method to correct skewed images as described in Projection profile based skew estimation algorithm for JBIG

compressed images. After obtaining a binary image, the idea is to rotate the image at various angles and generate a histogram of pixels in each iteration. To determine the skew angle, we compare the maximum difference between peaks and using this skew angle, rotate the image to correct the skew. The amount of peaks to determine can be adjusted by the `delta`

value, the lower the delta, the more peaks will be checked with the tradeoff that the process will take longer.

Before `->`

After

Skew angle: -2

Code

```
import cv2
import numpy as np
from scipy.ndimage import interpolation as inter
def correct_skew(image, delta=1, limit=5):
def determine_score(arr, angle):
data = inter.rotate(arr, angle, reshape=False, order=0)
histogram = np.sum(data, axis=1, dtype=float)
score = np.sum((histogram[1:] - histogram[:-1]) ** 2, dtype=float)
return histogram, score
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
scores = []
angles = np.arange(-limit, limit + delta, delta)
for angle in angles:
histogram, score = determine_score(thresh, angle)
scores.append(score)
best_angle = angles[scores.index(max(scores))]
(h, w) = image.shape[:2]
center = (w // 2, h // 2)
M = cv2.getRotationMatrix2D(center, best_angle, 1.0)
corrected = cv2.warpAffine(image, M, (w, h), flags=cv2.INTER_CUBIC, \
borderMode=cv2.BORDER_REPLICATE)
return best_angle, corrected
if __name__ == '__main__':
image = cv2.imread('1.jpg')
angle, corrected = correct_skew(image)
print('Skew angle:', angle)
cv2.imshow('corrected', corrected)
cv2.waitKey()
```

**Note:** You may have to adjust the `delta`

or `limit`

values depending on the image. The `delta`

value controls iteration step, it will iterate up until the `limit`

which controls the maximum angle. This method is straightforward by iteratively checking each angle + `delta`

and currently only works to correct skew in the range of +/- 5 degrees. If you need to correct at a larger angle, adjust the `limit`

value. For another approach to handle skew, take a look at rotate skewed image to upright position for an alternative method.