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

**URL:** <https://forum.opencv.org/t/how-do-i-locate-the-center-of-a-piece-of-paper-in-a-photo/11875>\
**Category:** Python\
**Tags:** programming\
**Created:** [February 5, 2023, 4:43am UTC](https://forum.opencv.org/t/how-do-i-locate-the-center-of-a-piece-of-paper-in-a-photo/11875 "2023-02-05T04:43:16Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Dev\_101](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/dev_101/32/6486_2.png) [@Dev\_101](https://forum.opencv.org/u/Dev_101)\
**Post date:** [February 5, 2023, 4:43am UTC](https://forum.opencv.org/t/how-do-i-locate-the-center-of-a-piece-of-paper-in-a-photo/11875/1 "2023-02-05T04:43:16Z")

</div>

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:

 ![Screenshot 2023-02-04 at 11.36.27 PM](https://us1.discourse-cdn.com/flex020/uploads/opencv/original/2X/5/593d356c4e71a14d7b2c93e9a7ffae24de102419.jpeg)

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](https://www.youtube.com/watch?v=PZsbROEpfNU)  
My Code:

```auto

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
    frame,mask,result = Thresh.thresh(frame)

    frameWPoints = frame.copy()
    warpThresh = mask.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
    return int(curve),frame,mask,warpFrame,warpThresh,imgWarpPoints,imgHist,complete

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 = vid.read()
        frame = cv2.resize(frame,(480,240))
        curve,frame,mask,warp,warpThresh,roi,histogram,complete = getCurve(frame)
        
        l1 =np.concatenate((frame,mask),axis=1)
        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()

```

Thanks in advance,  
Dev\_101

---

<div class="post-metadata">

**Author:** ![berak](https://avatars.discourse-cdn.com/v4/letter/b/85f322/32.png) [@berak](https://forum.opencv.org/u/berak)\
**Post date:** [February 5, 2023, 8:28am UTC](https://forum.opencv.org/t/how-do-i-locate-the-center-of-a-piece-of-paper-in-a-photo/11875/2 "2023-02-05T08:28:50Z")

</div>

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](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)

---

<div class="post-metadata">

**Author:** ![Dev\_101](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/dev_101/32/6486_2.png) [@Dev\_101](https://forum.opencv.org/u/Dev_101)\
**Post date:** [February 5, 2023, 3:15pm UTC](https://forum.opencv.org/t/how-do-i-locate-the-center-of-a-piece-of-paper-in-a-photo/11875/3 "2023-02-05T15:15:19Z")

</div>

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:

```auto
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])
    mask = cv2.inRange(imgHsv, lower, upper)
    result = cv2.bitwise_and(frame, frame, mask=mask)
 
    mask = cv2.cvtColor(mask, cv2.COLOR_GRAY2BGR)
    
    return frame,mask,result

```

ROI.py

```auto
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:

```auto

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
    frame,mask,result = Thresh.thresh(frame)

    frameWPoints = frame.copy()
    warpThresh = mask.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
    return int(curve),frame,mask,warpFrame,warpThresh,imgWarpPoints,imgHist,complete

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 = vid.read()
        frame = cv2.resize(frame,(480,240))
        curve,frame,mask,warp,warpThresh,roi,histogram,complete = getCurve(frame)
        
        l1 =np.concatenate((frame,mask),axis=1)
        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

---

<div class="post-metadata">

**Author:** ![berak](https://avatars.discourse-cdn.com/v4/letter/b/85f322/32.png) [@berak](https://forum.opencv.org/u/berak)\
**Post date:** [February 5, 2023, 3:17pm UTC](https://forum.opencv.org/t/how-do-i-locate-the-center-of-a-piece-of-paper-in-a-photo/11875/4 "2023-02-05T15:17:17Z")

</div>

> [@Dev\_101](#):
>
> I prefer the histogram approach because it is my first time using the OpenCV framework.

the histogram part is NOT from opencv

> [@Dev\_101](#):
>
> why it is not working properly, so any help would be appreciated,

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

---

<div class="post-metadata">

**Author:** ![Dev\_101](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/dev_101/32/6486_2.png) [@Dev\_101](https://forum.opencv.org/u/Dev_101)\
**Post date:** [February 5, 2023, 3:26pm UTC](https://forum.opencv.org/t/how-do-i-locate-the-center-of-a-piece-of-paper-in-a-photo/11875/5 "2023-02-05T15:26:12Z")

</div>

I understand, but I gave you the missing modules.

---

<div class="post-metadata">

**Author:** ![crackwitz](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/crackwitz/32/14_2.png) [@crackwitz](https://forum.opencv.org/u/crackwitz)\
**Post date:** [February 5, 2023, 5:46pm UTC](https://forum.opencv.org/t/how-do-i-locate-the-center-of-a-piece-of-paper-in-a-photo/11875/6 "2023-02-05T17:46:32Z")

</div>

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”.

---

<div class="post-metadata">

**Author:** ![Dev\_101](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/dev_101/32/6486_2.png) [@Dev\_101](https://forum.opencv.org/u/Dev_101)\
**Post date:** [February 5, 2023, 6:01pm UTC](https://forum.opencv.org/t/how-do-i-locate-the-center-of-a-piece-of-paper-in-a-photo/11875/7 "2023-02-05T18:01:08Z")

</div>

This is the image:  
 ![openCV](https://us1.discourse-cdn.com/flex020/uploads/opencv/original/2X/6/63ea4e78100ca87e38cf39d9a52ad1d206eb1d6b.png)

---

<div class="post-metadata">

**Author:** ![crackwitz](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/crackwitz/32/14_2.png) [@crackwitz](https://forum.opencv.org/u/crackwitz)\
**Post date:** [February 6, 2023, 12:13am UTC](https://forum.opencv.org/t/how-do-i-locate-the-center-of-a-piece-of-paper-in-a-photo/11875/8 "2023-02-06T00:13:16Z")

</div>

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
