# How do I locate the center of a piece of paper in a photo?

Hello,
I have adjusted my code and am no longer getting any errors. When I am creating a histogram to find the center point of a white paper I am getting it a bit off-center.

Can anyone help?

Here is an image:

I would like the yellow dot in the center of the paper.

A tutorial I have been using: Finding Lane Curve | Self Driving Car with Lane Detection using Raspberry Pi p.4 - YouTube
My Code:

``````
import cv2
import numpy as np
import Thresh
import ROI

def empty(x):
pass

def getHistogram(img,minPer=0.1,display=True):

histValues = np.sum(img,axis=0)
maxValue = np.max(histValues)
minValue = minPer*maxValue

indexArray = np.where(histValues>= minValue)
basePoint = int(np.average(indexArray))
w = img.shape[1]
h = img.shape[0]
print(type(w))

if display:
imgHist = np.zeros((img.shape[0],img.shape[1],3),np.uint8)
for x,intensity in enumerate(histValues):
temp=0
for i in intensity:
temp+= int(i)
cv2.line(imgHist,(int(x),int(w)),(int(x),int(h)-temp//255),(255,0,255),1)
cv2.circle(imgHist,(basePoint,int(h)),20,(0,255,255),cv2.FILLED)
return basePoint,imgHist

return basePoint

print(basePoint)
curveList = []
avgVal=10

def getCurve(frame):

# Step 1: Threhold Paper

frameWPoints = frame.copy()
warpFrame = frame.copy()

# Step 2: Define ROI
hT, wT, c = frame.shape
points = ROI.valTrackbars()
# Step 3: Warp Image
warpFrame = ROI.warpImg(warpFrame,points,wT,hT)
warpThresh = ROI.warpImg(warpThresh,points,wT,hT)
imgWarpPoints = ROI.drawPoints(frameWPoints,points)
# Step 4: Apply Histogram - Summation of Pixels
basePoint,imgHist = getHistogram(warpThresh)
# Step 5: Calculate Curve
# print(curveRaw)
# Step 6: Filter Curve

# Step 7: Display
#print(curve)
complete = frame
curve = 0

if __name__ == "__main__":

cv2.namedWindow("HSV")
cv2.resizeWindow("HSV", 640, 240)
cv2.createTrackbar("HUE Min", "HSV", 0, 255, empty)
cv2.createTrackbar("HUE Max", "HSV", 179, 255, empty)
cv2.createTrackbar("SAT Min", "HSV", 0, 255, empty)
cv2.createTrackbar("SAT Max", "HSV", 255, 255, empty)
cv2.createTrackbar("VALUE Min", "HSV", 113, 255, empty)
cv2.createTrackbar("VALUE Max", "HSV", 255, 255, empty)

intialTrackBarVals = [50, 108, 0, 140]
ROI.initializeTrackbars(intialTrackBarVals)

vid = cv2.VideoCapture(0)
while(1):
frame = cv2.resize(frame,(480,240))

l2 =np.concatenate((roi,warp,warpThresh),axis=1)
l3 =np.concatenate((histogram,complete),axis=1)
cv2.imshow("THRESH",l1)
cv2.imshow("TRANSFORM",l2)
cv2.imshow("RESULT",l3)

if cv2.waitKey(1) & 0xFF == ord('q'):
break

vid.release()

cv2.destroyAllWindows()

``````

Dev_101

i’d rather ditch the whole ROI / histogram approach, and try to find the center from the binary image using `cv2.moments()`
https://docs.opencv.org/4.x/d0/d49/tutorial_moments.html

(please be aware that noone here can reproduce your code due to missing ROI / Thresh modules)

Ok, I understand. I prefer the histogram approach because it is my first time using the OpenCV framework.

Here are all my modules:

thresh.py:

``````import cv2
import numpy as np

def empty(x):
pass

def thresh(frame):

frame = cv2.resize(frame, (480,240))

imgHsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

h_min = cv2.getTrackbarPos("HUE Min", "HSV")
h_max = cv2.getTrackbarPos("HUE Max", "HSV")
s_min = cv2.getTrackbarPos("SAT Min", "HSV")
s_max = cv2.getTrackbarPos("SAT Max", "HSV")
v_min = cv2.getTrackbarPos("VALUE Min", "HSV")
v_max = cv2.getTrackbarPos("VALUE Max", "HSV")

lower = np.array([h_min, s_min, v_min])
upper = np.array([h_max, s_max, v_max])

``````

ROI.py

``````import cv2
import numpy as np

def nothing(x):
pass

def warpImg (img,points,w,h,inv=False):
pts1 = np.float32(points)
pts2 = np.float32([[0,0],[w,0],[0,h],[w,h]])
if inv:
matrix = cv2.getPerspectiveTransform(pts2,pts1)
else:
matrix = cv2.getPerspectiveTransform(pts1,pts2)
imgWarp = cv2.warpPerspective(img,matrix,(w,h))
return imgWarp

def initializeTrackbars(intialTracbarVals,wT=480, hT=240):
cv2.namedWindow("Trackbars")
cv2.resizeWindow("Trackbars", 360, 240)
cv2.createTrackbar("Width Top", "Trackbars", intialTracbarVals[0],wT//2, nothing)
cv2.createTrackbar("Height Top", "Trackbars", intialTracbarVals[1], hT, nothing)
cv2.createTrackbar("Width Bottom", "Trackbars", intialTracbarVals[2],wT//2, nothing)
cv2.createTrackbar("Height Bottom", "Trackbars", intialTracbarVals[3], hT, nothing)

def valTrackbars(wT=480, hT=240):
widthTop = cv2.getTrackbarPos("Width Top", "Trackbars")
heightTop = cv2.getTrackbarPos("Height Top", "Trackbars")
widthBottom = cv2.getTrackbarPos("Width Bottom", "Trackbars")
heightBottom = cv2.getTrackbarPos("Height Bottom", "Trackbars")
points = np.float32([(widthTop, heightTop), (wT-widthTop, heightTop),
(widthBottom , heightBottom ), (wT-widthBottom, heightBottom)])
return points

def drawPoints(img,points):
for x in range( 0,4):
cv2.circle(img,(int(points[x][0]),int(points[x][1])),15,(0,0,255),cv2.FILLED)
return img
``````

curve.py:

``````
import cv2
import numpy as np
import Thresh
import ROI

def empty(x):
pass

def getHistogram(img,minPer=0.1,display=True):

histValues = np.sum(img,axis=0)
maxValue = np.max(histValues)
minValue = minPer*maxValue

indexArray = np.where(histValues>= minValue)
basePoint = int(np.average(indexArray))
w = img.shape[1]
h = img.shape[0]
print(type(w))

if display:
imgHist = np.zeros((img.shape[0],img.shape[1],3),np.uint8)
for x,intensity in enumerate(histValues):
temp=0
for i in intensity:
temp+= int(i)
cv2.line(imgHist,(int(x),int(w)),(int(x),int(h)-temp//255),(255,0,255),1)
cv2.circle(imgHist,(basePoint,int(h)),20,(0,255,255),cv2.FILLED)
return basePoint,imgHist

return basePoint

print(basePoint)
curveList = []
avgVal=10

def getCurve(frame):

# Step 1: Threhold Paper

frameWPoints = frame.copy()
warpFrame = frame.copy()

# Step 2: Define ROI
hT, wT, c = frame.shape
points = ROI.valTrackbars()
# Step 3: Warp Image
warpFrame = ROI.warpImg(warpFrame,points,wT,hT)
warpThresh = ROI.warpImg(warpThresh,points,wT,hT)
imgWarpPoints = ROI.drawPoints(frameWPoints,points)
# Step 4: Apply Histogram - Summation of Pixels
basePoint,imgHist = getHistogram(warpThresh)
# Step 5: Calculate Curve
# print(curveRaw)
# Step 6: Filter Curve

# Step 7: Display
#print(curve)
complete = frame
curve = 0

if __name__ == "__main__":

cv2.namedWindow("HSV")
cv2.resizeWindow("HSV", 640, 240)
cv2.createTrackbar("HUE Min", "HSV", 0, 255, empty)
cv2.createTrackbar("HUE Max", "HSV", 179, 255, empty)
cv2.createTrackbar("SAT Min", "HSV", 0, 255, empty)
cv2.createTrackbar("SAT Max", "HSV", 255, 255, empty)
cv2.createTrackbar("VALUE Min", "HSV", 113, 255, empty)
cv2.createTrackbar("VALUE Max", "HSV", 255, 255, empty)

intialTrackBarVals = [50, 108, 0, 140]
ROI.initializeTrackbars(intialTrackBarVals)

vid = cv2.VideoCapture(0)
while(1):
frame = cv2.resize(frame,(480,240))

l2 =np.concatenate((roi,warp,warpThresh),axis=1)
l3 =np.concatenate((histogram,complete),axis=1)
cv2.imshow("THRESH",l1)
cv2.imshow("TRANSFORM",l2)
cv2.imshow("RESULT",l3)

if cv2.waitKey(1) & 0xFF == ord('q'):
break

vid.release()

cv2.destroyAllWindows()

``````

Again,
I have tried for hours and don’t understand why it is not working properly, so any help would be appreciated,

Thanks,
Dev101

the histogram part is NOT from opencv

again, please realize, that we cannot help with code we cant reproduce

I understand, but I gave you the missing modules.

take one picture and save it. provide this picture as input for everyone to work on. make sure it is not a screenshot or anything like that, but the original untouched picture.

we can’t use your webcam, hence “not reproducible”.

This is the image:

that picture is 480x240. is that the resolution you expect to work with?

and you need to find… two corners in that picture, or four corners?

if you need the center, but the center isn’t marked, you need the four corners