Python OpenCV ile Açı Ölçümündeki Hata

Merhabalar,
İki çizgi arasındaki açıyı OpenCV ile bulmak istiyoruz. Yazdığımız kod ile, belirleyemediğimiz bir sorun nedeniyle istediğimiz şekilde açı hesaplaması yapamıyoruz.
Amacımız, resimde bulunan kırmızı renkteki bir cisim ile resimde bulunan farklı renkteki bazı cisimlerin arasındaki açıyı hesaplamak. Bunun için kırmızı renkteki nesnenin ortasından sağ tarafına doğru bir X ekseni çizdik ve açıyı bulmasını sağlayacak kodu yazdık. Ancak bu kod istediğimiz şekilde açı hesaplaması yapmıyor. Şöyleki:
Koordinat sistemine göre, 0-90° alanındaki açıları negatif, 90-180° alanındaki açıları ise pozitif olacak şekilde gösteriyor. Görseller üzerinden daha kolay anlaşılacaktır. Örnek olarak bir açı ölçerin üzerine çizdiğimiz bu resimlere bakalım:
Bu resimde kırmızı ile mavi nesne arasındaki açı -65° olarak ölçülmüş:

(yeni kullanıcılar 1 foto ile sınırlandırılmış diğer fotoları da farklı bir hesaptan yükleyeceğim)

Kısacası bizler açının 360° üzerinden ve pozitif olarak hesaplanmasını istiyoruz. Kodun tamamını aşağıya bırakıyorum. Python ve OpenCV bilgimiz kısıtlı. Yardımcı olacak arkadaşlara şimdiden teşekkür eder hayırlı akşamlar dilerim.
(açı hesaplaması ile ilgili kodları “def kırmızı()” fonksiyonu ve sonraki satırlarda bulabilirsiniz. Gözden kaçan yer olması ihtimaline karşın kodların tümünü yazdım)

import cv2 as cv
import numpy as np
import math

data = cv.imread("angle1.jpg")
x, y, w, h = 0, 0, 0, 0
data = cv.medianBlur(data,5)
dataHsv=cv.cvtColor(data,cv.COLOR_BGR2HSV)

a = 0
b = 0
maviDeg = None
sariDeg = None
kirmiziDeg = None
xDeg = None
yesilDeg = None

def mavi():
    global a
    global b
    global maviDeg
    mlower_color = np.array([75,100,100])#Mavi renk eşik değerleri.
    mupper_color = np.array([130,255,255])
    mask = cv.inRange(dataHsv, mlower_color,mupper_color)
    mask = cv.dilate(mask,(3,3),iterations=3)
    contour, _ = cv.findContours(mask,cv.RETR_TREE,cv.CHAIN_APPROX_SIMPLE)
    for cnt in contour:
        area = cv.contourArea(cnt)     
        if area > 480:#Kontur minimum değeri.
            x, y, w, h = cv.boundingRect(cnt) #Diktörtgen kutu çizimi.
            cv.rectangle(data, (x, y), (x + w, y + h), (0, 255, 0), 3)
            cv.putText(	data, "Mavi Hedef", (x-35,y), cv.FONT_HERSHEY_SIMPLEX, 1,(0,0,0), 2, cv.LINE_AA  )
            a = x+(w/2)  # Çerçeve genişliğinin yarısı
            b = y+(h/2)  # Çerçeve yüksekliğinin yarısı
            cv.circle(data,((int(a)),(int(b))), 1, (0,255,0), 6)
            maviDeg = ([int(a),int(b)])
            #print("mavi",a,b)

def sarı():
    global a
    global b
    global sariDeg
    slower_color = np.array([22,100,100])#Sarı renk eşik değerleri.
    supper_color = np.array([38,255,255])
    mask = cv.inRange(dataHsv, slower_color,supper_color)
    mask = cv.dilate(mask,(3,3),iterations=3)
    contour, _ = cv.findContours(mask,cv.RETR_TREE,cv.CHAIN_APPROX_SIMPLE)
    for cnt in contour:
        area = cv.contourArea(cnt)     
        if area > 480:#Kontur minimum değeri.
            x, y, w, h = cv.boundingRect(cnt) #Diktörtgen kutu çizimi.
            cv.rectangle(data, (x, y), (x + w, y + h), (0, 255, 0), 3)
            cv.putText(	data, "Sari Hedef", (x-35,y), cv.FONT_HERSHEY_SIMPLEX, 1,(0,0,0), 2, cv.LINE_AA  )
            a = x+(w/2)  # Çerçeve genişliğinin yarısı
            b = y+(h/2)  # Çerçeve yüksekliğinin yarısı
            cv.circle(data,((int(a)),(int(b))), 1, (0,255,0), 6)
            sariDeg = ([int(a),int(b)])

def yeşil():
    global a
    global b
    global yesilDeg
    ylower_color = np.array([38,100,100])#Yeşil renk eşik değerleri.
    yupper_color = np.array([75,255,255])
    mask = cv.inRange(dataHsv, ylower_color,yupper_color)
    mask = cv.dilate(mask,(3,3),iterations=3)
    contour, _ = cv.findContours(mask,cv.RETR_TREE,cv.CHAIN_APPROX_SIMPLE)
    for cnt in contour:
        area = cv.contourArea(cnt)     
        if area > 480:#Kontur minimum değeri.
            x, y, w, h = cv.boundingRect(cnt) #Diktörtgen kutu çizimi.
            cv.rectangle(data, (x, y), (x + w, y + h), (0, 255, 0), 3)
            cv.putText(	data, "Yesil Hedef", (x-35,y), cv.FONT_HERSHEY_SIMPLEX, 1,(0,0,0), 2, cv.LINE_AA  )
            a = x+(w/2)  # Çerçeve genişliğinin yarısı
            b = y+(h/2)  # Çerçeve yüksekliğinin yarısı
            cv.circle(data,((int(a)),(int(b))), 1, (0,255,0), 6)
            yesilDeg = ([int(a),int(b)])

def kırmızı():
    global kirmiziDeg
    global xDeg
    klower_color = np.array([160,100,100])#Kırrmızı renk eşik değerleri.
    kupper_color = np.array([179,255,255])
    mask = cv.inRange(dataHsv, klower_color,kupper_color)
    mask = cv.dilate(mask,(3,3),iterations=3)
    contour, _ = cv.findContours(mask,cv.RETR_TREE,cv.CHAIN_APPROX_SIMPLE)
    for cnt in contour:
        area = cv.contourArea(cnt)     
        if area > 480:#Kontur minimum değeri.
            x, y, w, h = cv.boundingRect(cnt) #Diktörtgen kutu çizimi.
            cv.rectangle(data, (x, y), (x + w, y + h), (0, 255, 0), 3)
            cv.putText(	data, "Kirmizi", (x,y), cv.FONT_HERSHEY_SIMPLEX, 1,(0,0,0), 2, cv.LINE_AA  )
            a1 = x+(w/2)  # Çerçeve genişliğinin yarısı
            b1 = y+(h/2)  # Çerçeve yüksekliğinin yarısı
            cv.circle(data,((int(a1)),(int(b1))), 1, (0,255,0), 6)
            kirmiziDeg = ([int(a1),int(b1)])
            cv.line(data, (int(a1), int(b1)), (int(a), int(b)), (0, 0, 0), 5)            
            cv.line(data, (int(a1), int(b1)), (int(a1+a1), int(b1)), (0, 0, 0), 5)
            xDeg = ([a1+a1,b1])
            

def gradient(pt1,pt2):
    return (pt2[1]-pt1[1])/(pt2[0]-pt1[0])
def getAngle(pointsList):
    pt1, pt2, pt3 = pointsList[-3:]
    m1 = gradient(pt1,pt2)
    m2 = gradient(pt1,pt3)
    angR = math.atan((m2-m1)/(1+(m2*m1))) 
    angD = round(math.degrees(angR))
    print(angD,"°",sep="")
    cv.putText(data,str(angD),(pt1[0]+30,pt1[1]),cv.FONT_HERSHEY_COMPLEX,1.5,(0,0,0),2)

renk = input("sarı, yeşil, mavi\nÇizgi çekilecek renk: ")
if(renk == "sarı"):
    sarı()
    kırmızı()
    spointsList =(kirmiziDeg, xDeg, sariDeg)
    getAngle(spointsList)
    cv.imshow('Resim', data)
elif(renk == "mavi"):
    mavi()
    kırmızı()
    mpointsList =(kirmiziDeg, xDeg, maviDeg)
    getAngle(mpointsList)
    cv.imshow('Resim', data)
elif(renk == "yeşil"):
    yeşil()
    kırmızı()
    ypointsList =(kirmiziDeg, xDeg, yesilDeg)
    getAngle(ypointsList)
    cv.imshow('Resim', data)



cv.waitKey(0)
cv.destroyAllWindows()

Merhaba,

Ben olsaydım vektör çarpımından giderdim. Yani şöyle.

cos θ= (u • v) / (||u|| . ||v||)

Bu formülden tetayı çekerdim. Daha sonra ise mavi noktanın koordinat düzleminde hangi bölgede olduğuna bakardım.( 1. bölge, 2. bölge,3. bölge, 4. bölge)

Eğer mavi nokta 1. bölgede ise

cevap = acos( (u • v) / (||u|| . ||v||)) + 0°

Eğer mavi nokta 2. bölgede ise

cevap = acos( (u • v) / (||u|| . ||v||)) + 90°

Eğer mavi nokta 3. bölgede ise

cevap = acos( (u • v) / (||u|| . ||v||)) + 180°

Eğer mavi nokta 4. bölgede ise

cevap = acos( (u • v) / (||u|| . ||v||)) + 270°

Eğer bu formülleri anlayamadıysanız dot product diye falan aratabilirsiniz. Bütün bu anlattıklarım lineer cebir konusudur. Daha detaylı bir açıklama yapacaktım da uyumam lazım. Yarın bu postu editlemek suretiyle ek bir açıklama yaparım.

Bir de birimlere dikkat etmedim şimdi. Oradaki ters, radyan cinsinden de olabilir. Ona da bı bakıp tekrar bir şeyler yazarım. Ama fikrim bu şekilde.

1 Beğeni

Hocam cevabınız için teşekkür ederim. Biz de dediğiniz gibi 1. bölge 2. bölge 3. bölge 4. bölge olarak ölçmek istiyoruz. Ancak belirttiğiniz formüllerden ne yazık ki hiçbir şey anlamadım. Python’da, özellikle matematiksel hesaplama konusunda bilgimiz yok denecek kadar az. Verdiğim kodda yapmış olduğumuz hesaplamayı da internetten, yabancı kaynaklardan vs. deneme/yanılma yoluyla yaptık.
Müsait olduğunuz zaman bahsettiğiniz şekildeki kullanımın bizim kodumuza göre uyarlanmış halini yazarsanız çok mutlu oluruz.
Hayırlı günler dilerim.

Resimli örnek üzerinde ihtiyacınız daha güzel anlaşılmış.

Daha önce verdiğim linkteki örnekten faydalanmaya çalışmanız da iyi bir şey. Denemeden olmaz en azından denemişsiniz. Ve ufak bir yerde takılmışsınız.

 if angD<0:
        angD=180+angD

Şeklinde bir ilave size bunu sağlayacaktır. Açının başlangıç noktası ayarları ile alakalı. Aslnda o da ayarlanabilir ama şu an denediğim kod satırı bu olduğundan bu çözümü bırakayım.

image

def getAngle(pointsList):
    pt1, pt2, pt3 = pointsList[-3:]
    m1 = gradient(pt1,pt2)
    m2 = gradient(pt1,pt3)
    angR = math.atan((m2-m1)/(1+(m2*m1))) 
    angD = round(math.degrees(angR))
    
    # Bu kısma ilave edilen kod:
    if angD<0:
        angD=180+angD

    print(angD,"°",sep="")
    cv.putText(data,str(angD),(pt1[0]+30,pt1[1]),cv.FONT_HERSHEY_COMPLEX,1.5,(0,0,0),2)

Diğer bir katılımcının söylediği gibi birden çok yöntem var vektörel çözüm ve 360 tarama için de farklı çözümler var. Şu an siz 0-180 arası tarama yapıyorsanız bu ufak düzeltme işinizi görecektir.

Ama 360 derece bir açı hesabı lazımsa ona da alternatifler bırakabiliriz.

1 Beğeni

Hocam cevabınız için teşekkür ederim. Belirttiğiniz kodu ekleyerek negatif değer sorununu çözdük. Ancak ölçüm yaparken sağ tarafa doğru çektiğimiz X ekseni yerine sol taraftaki eksen ile arasındaki açıyı ölçüyor. Fotoda görüldüğü üzere 65° ölçmesi gerekirken 115° olarak ölçmüş:


Kodlarda neyi yanlış yaptık acaba?

Bir de biz 360° üzerinden hesaplama yapılmasını istiyoruz. Bunu nasıl yapabiliriz?

import cv2 as cv
import numpy as np
import math

data = cv.imread("test.jpg")
x, y, w, h = 0, 0, 0, 0
data = cv.medianBlur(data,5)
dataHsv=cv.cvtColor(data,cv.COLOR_BGR2HSV)

a = 0
b = 0
maviDeg = None
sariDeg = None
kirmiziDeg = None
xDeg = None
yesilDeg = None

def mavi():
    global a
    global b
    global maviDeg
    mlower_color = np.array([75,100,100])#Mavi renk eşik değerleri.
    mupper_color = np.array([130,255,255])
    mask = cv.inRange(dataHsv, mlower_color,mupper_color)
    mask = cv.dilate(mask,(3,3),iterations=3)
    contour, _ = cv.findContours(mask,cv.RETR_TREE,cv.CHAIN_APPROX_SIMPLE)
    for cnt in contour:
        area = cv.contourArea(cnt)     
        if area > 480:#Kontur minimum değeri.
            x, y, w, h = cv.boundingRect(cnt) #Diktörtgen kutu çizimi.
            cv.rectangle(data, (x, y), (x + w, y + h), (0, 255, 0), 3)
            cv.putText(	data, "Mavi Hedef", (x-35,y), cv.FONT_HERSHEY_SIMPLEX, 1,(0,0,0), 2, cv.LINE_AA  )
            a = x+(w/2)  # Çerçeve genişliğinin yarısı
            b = y+(h/2)  # Çerçeve yüksekliğinin yarısı
            cv.circle(data,((int(a)),(int(b))), 1, (0,255,0), 6)
            maviDeg = ([int(a),int(b)])
            #print("mavi",a,b)

def sarı():
    global a
    global b
    global sariDeg
    slower_color = np.array([22,100,100])#Sarı renk eşik değerleri.
    supper_color = np.array([38,255,255])
    mask = cv.inRange(dataHsv, slower_color,supper_color)
    mask = cv.dilate(mask,(3,3),iterations=3)
    contour, _ = cv.findContours(mask,cv.RETR_TREE,cv.CHAIN_APPROX_SIMPLE)
    for cnt in contour:
        area = cv.contourArea(cnt)     
        if area > 480:#Kontur minimum değeri.
            x, y, w, h = cv.boundingRect(cnt) #Diktörtgen kutu çizimi.
            cv.rectangle(data, (x, y), (x + w, y + h), (0, 255, 0), 3)
            cv.putText(	data, "Sari Hedef", (x-35,y), cv.FONT_HERSHEY_SIMPLEX, 1,(0,0,0), 2, cv.LINE_AA  )
            a = x+(w/2)  # Çerçeve genişliğinin yarısı
            b = y+(h/2)  # Çerçeve yüksekliğinin yarısı
            cv.circle(data,((int(a)),(int(b))), 1, (0,255,0), 6)
            sariDeg = ([int(a),int(b)])

def yeşil():
    global a
    global b
    global yesilDeg
    ylower_color = np.array([38,100,100])#Yeşil renk eşik değerleri.
    yupper_color = np.array([75,255,255])
    mask = cv.inRange(dataHsv, ylower_color,yupper_color)
    mask = cv.dilate(mask,(3,3),iterations=3)
    contour, _ = cv.findContours(mask,cv.RETR_TREE,cv.CHAIN_APPROX_SIMPLE)
    for cnt in contour:
        area = cv.contourArea(cnt)     
        if area > 480:#Kontur minimum değeri.
            x, y, w, h = cv.boundingRect(cnt) #Diktörtgen kutu çizimi.
            cv.rectangle(data, (x, y), (x + w, y + h), (0, 255, 0), 3)
            cv.putText(	data, "Yesil Hedef", (x-35,y), cv.FONT_HERSHEY_SIMPLEX, 1,(0,0,0), 2, cv.LINE_AA  )
            a = x+(w/2)  # Çerçeve genişliğinin yarısı
            b = y+(h/2)  # Çerçeve yüksekliğinin yarısı
            cv.circle(data,((int(a)),(int(b))), 1, (0,255,0), 6)
            yesilDeg = ([int(a),int(b)])

def kırmızı():
    global kirmiziDeg
    global xDeg
    klower_color = np.array([160,100,100])#Kırrmızı renk eşik değerleri.
    kupper_color = np.array([179,255,255])
    mask = cv.inRange(dataHsv, klower_color,kupper_color)
    mask = cv.dilate(mask,(3,3),iterations=3)
    contour, _ = cv.findContours(mask,cv.RETR_TREE,cv.CHAIN_APPROX_SIMPLE)
    for cnt in contour:
        area = cv.contourArea(cnt)     
        if area > 480:#Kontur minimum değeri.
            x, y, w, h = cv.boundingRect(cnt) #Diktörtgen kutu çizimi.
            cv.rectangle(data, (x, y), (x + w, y + h), (0, 255, 0), 3)
            cv.putText(	data, "Kirmizi", (x,y), cv.FONT_HERSHEY_SIMPLEX, 1,(0,0,0), 2, cv.LINE_AA  )
            a1 = x+(w/2)  # Çerçeve genişliğinin yarısı
            b1 = y+(h/2)  # Çerçeve yüksekliğinin yarısı
            cv.circle(data,((int(a1)),(int(b1))), 1, (0,255,0), 6)
            kirmiziDeg = ([int(a1),int(b1)])
            cv.line(data, (int(a1), int(b1)), (int(a), int(b)), (0, 0, 0), 5)            
            cv.line(data, (int(a1), int(b1)), (int(a1+a1), int(b1)), (0, 0, 0), 5)
            xDeg = ([a1+a1,b1])
            

def getAngle(pointList):
    p1, p2, p3 = pointList[-3:]
    ang = math.degrees(math.atan2(p3[1]-p2[1], p3[0]-p2[0]) - math.atan2(p1[1]-p2[1], p1[0]-p2[0]))
    
    if ang < 0:
        angD= round (ang + 360)
    else: 
         angD= round(ang )
    cv.putText(data,str(angD),(p2[0]-40,p2[1]-20),cv.FONT_HERSHEY_COMPLEX,
                1.5,(0,0,255),2)

renk = input("sarı, yeşil, mavi\nÇizgi çekilecek renk: ")
if(renk == "sarı"):
    sarı()
    kırmızı()
    spointsList =(sariDeg, kirmiziDeg, xDeg )
    print(spointsList)
    getAngle(spointsList)
    cv.imshow('Resim', data)
elif(renk == "mavi"):
    mavi()
    kırmızı()
    mpointsList =(maviDeg, kirmiziDeg, xDeg )
    getAngle(mpointsList)
    cv.imshow('Resim', data)
elif(renk == "yeşil"):
    yeşil()
    kırmızı()
    ypointsList =(yesilDeg, kirmiziDeg, xDeg )
    getAngle(ypointsList)
    cv.imshow('Resim', data)



cv.waitKey(0)
cv.destroyAllWindows()

360 derece için fonksiyonu değiştirdim biraz.

Sonrasında, sizin kullandığınız nokta verilerinin giriş sırasını değiştirdim.

Kırmızı, yeşil mavi için açı sorunu yaşamadım.

Yeşil için deneyemiyorum sizin yeşil kareleri yakalıyor. Ondan temiz bir resim istemiştim.

Kendi kullandığım test kodu da aşağıda.

import cv2
import math
 
path = 'test.jpg'
img = cv2.imread(path)
pointsList = []
 
def mousePoints(event,x,y,flags,params):
    if event == cv2.EVENT_LBUTTONDOWN:
        size = len(pointsList)
        if size != 0 and size % 3 != 0:
            cv2.line(img,tuple(pointsList[round((size-1)/3)*3]),(x,y),(0,0,255),2)
        cv2.circle(img,(x,y),5,(0,0,255),cv2.FILLED)
        pointsList.append([x,y])
 
 

def getAngle(pointList):
    b, a, c = pointList[-3:]
    ang = math.degrees(math.atan2(c[1]-b[1], c[0]-b[0]) - math.atan2(a[1]-b[1], a[0]-b[0]))
    
    if ang < 0:
        angD= round(ang + 360)
    else: 
         angD= round(ang )
    cv2.putText(img,str(angD),(a[0]-40,b[1]-20),cv2.FONT_HERSHEY_COMPLEX,
                1.5,(0,0,255),2)
    
    
 

while True:
 
 
    if len(pointsList) % 3 == 0 and len(pointsList) !=0:
        getAngle(pointsList)
 
    cv2.imshow('Image',img)
    cv2.setMouseCallback('Image',mousePoints)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        pointsList = []
        img = cv2.imread(path)

Bununla da fonksiyonun 360 derece kontrolünü yapabilirsiniz.

Varsa hata haber bekliyorum kolay gelsin.

1 Beğeni

3 nokta uzerinden açı hesaplamak için 3 noktanın koordinatı yeterlidir. Öncelikle 2 nokta arasındaki uzaklık formülü ile 3 kenar uzunluğu bilinen üçgen oluştur ve 3 kenarı bilinen üçgen üzerinden kosinüs teoremi ile açıyı bul.

Hocam biraz geç cevaplıyorum kusura bakmayın. Test için bir foto ekliyorum ben de deneyeceğim şimdi siz de deneyin isterseniz.
test

Mavi:

image

Sarı:

image

Yeşil:

image

Ben bir sorun göremedim. Olmuş galiba.

Çalışan kodu da buraya bırakayım, dağınık yazıyorum arayan bulamıyor.

import cv2 as cv
import numpy as np
import math

data = cv.imread("test.jpg")
x, y, w, h = 0, 0, 0, 0
data = cv.medianBlur(data,5)
dataHsv=cv.cvtColor(data,cv.COLOR_BGR2HSV)

a = 0
b = 0
maviDeg = None
sariDeg = None
kirmiziDeg = None
xDeg = None
yesilDeg = None

def mavi():
    global a
    global b
    global maviDeg
    mlower_color = np.array([75,100,100])#Mavi renk eşik değerleri.
    mupper_color = np.array([130,255,255])
    mask = cv.inRange(dataHsv, mlower_color,mupper_color)
    mask = cv.dilate(mask,(3,3),iterations=3)
    contour, _ = cv.findContours(mask,cv.RETR_TREE,cv.CHAIN_APPROX_SIMPLE)
    for cnt in contour:
        area = cv.contourArea(cnt)     
        if area > 480:#Kontur minimum değeri.
            x, y, w, h = cv.boundingRect(cnt) #Diktörtgen kutu çizimi.
            cv.rectangle(data, (x, y), (x + w, y + h), (0, 255, 0), 3)
            cv.putText(	data, "Mavi Hedef", (x-35,y), cv.FONT_HERSHEY_SIMPLEX, 1,(0,0,0), 2, cv.LINE_AA  )
            a = x+(w/2)  # Çerçeve genişliğinin yarısı
            b = y+(h/2)  # Çerçeve yüksekliğinin yarısı
            cv.circle(data,((int(a)),(int(b))), 1, (0,255,0), 6)
            maviDeg = ([int(a),int(b)])
            #print("mavi",a,b)

def sarı():
    global a
    global b
    global sariDeg
    slower_color = np.array([22,100,100])#Sarı renk eşik değerleri.
    supper_color = np.array([38,255,255])
    mask = cv.inRange(dataHsv, slower_color,supper_color)
    mask = cv.dilate(mask,(3,3),iterations=3)
    contour, _ = cv.findContours(mask,cv.RETR_TREE,cv.CHAIN_APPROX_SIMPLE)
    for cnt in contour:
        area = cv.contourArea(cnt)     
        if area > 480:#Kontur minimum değeri.
            x, y, w, h = cv.boundingRect(cnt) #Diktörtgen kutu çizimi.
            cv.rectangle(data, (x, y), (x + w, y + h), (0, 255, 0), 3)
            cv.putText(	data, "Sari Hedef", (x-35,y), cv.FONT_HERSHEY_SIMPLEX, 1,(0,0,0), 2, cv.LINE_AA  )
            a = x+(w/2)  # Çerçeve genişliğinin yarısı
            b = y+(h/2)  # Çerçeve yüksekliğinin yarısı
            cv.circle(data,((int(a)),(int(b))), 1, (0,255,0), 6)
            sariDeg = ([int(a),int(b)])

def yeşil():
    global a
    global b
    global yesilDeg
    ylower_color = np.array([38,100,100])#Yeşil renk eşik değerleri.
    yupper_color = np.array([75,255,255])
    mask = cv.inRange(dataHsv, ylower_color,yupper_color)
    mask = cv.dilate(mask,(3,3),iterations=3)
    contour, _ = cv.findContours(mask,cv.RETR_TREE,cv.CHAIN_APPROX_SIMPLE)
    for cnt in contour:
        area = cv.contourArea(cnt)     
        if area > 480:#Kontur minimum değeri.
            x, y, w, h = cv.boundingRect(cnt) #Diktörtgen kutu çizimi.
            cv.rectangle(data, (x, y), (x + w, y + h), (0, 255, 0), 3)
            cv.putText(	data, "Yesil Hedef", (x-35,y), cv.FONT_HERSHEY_SIMPLEX, 1,(0,0,0), 2, cv.LINE_AA  )
            a = x+(w/2)  # Çerçeve genişliğinin yarısı
            b = y+(h/2)  # Çerçeve yüksekliğinin yarısı
            cv.circle(data,((int(a)),(int(b))), 1, (0,255,0), 6)
            yesilDeg = ([int(a),int(b)])

def kırmızı():
    global kirmiziDeg
    global xDeg
    klower_color = np.array([160,100,100])#Kırrmızı renk eşik değerleri.
    kupper_color = np.array([179,255,255])
    mask = cv.inRange(dataHsv, klower_color,kupper_color)
    mask = cv.dilate(mask,(3,3),iterations=3)
    contour, _ = cv.findContours(mask,cv.RETR_TREE,cv.CHAIN_APPROX_SIMPLE)
    for cnt in contour:
        area = cv.contourArea(cnt)     
        if area > 480:#Kontur minimum değeri.
            x, y, w, h = cv.boundingRect(cnt) #Diktörtgen kutu çizimi.
            cv.rectangle(data, (x, y), (x + w, y + h), (0, 255, 0), 3)
            cv.putText(	data, "Kirmizi", (x,y), cv.FONT_HERSHEY_SIMPLEX, 1,(0,0,0), 2, cv.LINE_AA  )
            a1 = x+(w/2)  # Çerçeve genişliğinin yarısı
            b1 = y+(h/2)  # Çerçeve yüksekliğinin yarısı
            cv.circle(data,((int(a1)),(int(b1))), 1, (0,255,0), 6)
            kirmiziDeg = ([int(a1),int(b1)])
            cv.line(data, (int(a1), int(b1)), (int(a), int(b)), (0, 0, 0), 5)            
            cv.line(data, (int(a1), int(b1)), (int(a1+a1), int(b1)), (0, 0, 0), 5)
            xDeg = ([a1+a1,b1])
            

def getAngle(pointList):
    p1, p2, p3 = pointList[-3:]
    ang = math.degrees(math.atan2(p3[1]-p2[1], p3[0]-p2[0]) - math.atan2(p1[1]-p2[1], p1[0]-p2[0]))
    
    if ang < 0:
        angD= round (ang + 360)
    else: 
         angD= round(ang )
    cv.putText(data,str(angD),(p2[0]-40,p2[1]-20),cv.FONT_HERSHEY_COMPLEX,
                1.5,(0,0,255),2)

renk = input("sarı, yeşil, mavi\nÇizgi çekilecek renk: ")
if(renk == "sarı"):
    sarı()
    kırmızı()
    spointsList =(sariDeg, kirmiziDeg, xDeg )
    print(spointsList)
    getAngle(spointsList)
    cv.imshow('Resim', data)
elif(renk == "mavi"):
    mavi()
    kırmızı()
    mpointsList =(maviDeg, kirmiziDeg, xDeg )
    getAngle(mpointsList)
    cv.imshow('Resim', data)
elif(renk == "yeşil"):
    yeşil()
    kırmızı()
    ypointsList =(yesilDeg, kirmiziDeg, xDeg )
    getAngle(ypointsList)
    cv.imshow('Resim', data)



cv.waitKey(0)
cv.destroyAllWindows()
2 Beğeni

Hocam çok teşekkür ederiz. Sayenizde sorunu çözdük şimdi de sıradaki sorunlarla uğraşacağız. Tekrardan teşekkür eder hayırlı günler dileriz.

1 Beğeni

Siz tavsiyelerimi dinlemiş uğraşmışsınız, yapamazsanız tabi ki yardım ederiz. Elinize sağlık iyi getirmişsiniz kodu ben ufak tefek düzeltmeler yaptım.

İşinize yaradıysa ne mutlu. Size de kolay gelsin.

1 Beğeni

Hocam öncelikle her şey için teşekkür ederiz dün anlaşın birbirimizi yanlış anlamışız. Tabi ki de önce kodları kendimiz yazacağız hazır kod peşinde değildik. Biri bizim yerimize yazsın gibisinden… Sorunun çözülmesi aramızdaki sıkıntının da çözülmesine vesile olmuştur inşallah. Tekrardan teşekkür eder iyi günler dileriz.

2 Beğeni
  • Aci hesaplamak icin atan yerine atan2 kullanilir. gradient’a filan gerek yok; direk Δy ve Δx aliyor.

  • Uc nokta alip aralarindaki aciyi donduren bir fonksiyon lazim. Ismi itibariyle getAngle’in bunu yapmasi gerek. Aciyi yaziya cevirip resme basmak baskasinin gorevi. (Bunu data degiskeninin getAngle fonksiyonunda tanimli olmamasindan da gorebiliyoruz.)

  • Ilk cizgi her zaman ayni oldugu icin yollanmayabilir bile. Fonksiyona kirmizi ve diger noktanin koordinatlari, hatta direk farklari yollanabilir.

Bu nasil bir formul? atan direk (Δy / Δx) almiyor mu?

3 boyutta evet de, 2 boyutta gerek yok.

Hocam sorun çözüldü cevabınız için teşekkür ederiz.

Evet yok hocam. Şu kaynaktan faydalandılar:

Angle-Finder/angleFinder.py at master · murtazahassan/Angle-Finder · GitHub

Burada eğim ve açı kullanarak iki fonksiyon kullanmış.

def gradient(pt1,pt2):
    return (pt2[1]-pt1[1])/(pt2[0]-pt1[0])
 
def getAngle(pointsList):
    pt1, pt2, pt3 = pointsList[-3:]
    m1 = gradient(pt1,pt2)
    m2 = gradient(pt1,pt3)
    angR = math.atan((m2-m1)/(1+(m2*m1)))
    angD = round(math.degrees(angR))
 
    cv2.putText(img,str(angD),(pt1[0]-40,pt1[1]-20),cv2.FONT_HERSHEY_COMPLEX,
                1.5,(0,0,255),2)
 

Şeklinde. Bunu derleyip toplayıp tek fonksiyona sıkıştırdım, tabi ki farklı yaklaşımlar da olabilir.

Evet haklısınız, fonksiyonlar kendi içinde mümkün olduğunca bağımsız olmalılar.

Üç yerde text yazmamak için fonksiyon içinde bırakılmış. Ama dediğiniz gibi fonksiyonun ruhuna uygun olsun.

def getAngle(pointList):
    p1, p2, p3 = pointList[-3:]
    ang = math.degrees(math.atan2(p3[1]-p2[1], p3[0]-p2[0]) - math.atan2(p1[1]-p2[1], p1[0]-p2[0]))
    
    if ang < 0:
        angD= round (ang + 360)
    else: 
         angD= round(ang )
    
    return angD

Artık sadece açı döndürüyor.

Tabi bu da bir yöntem ama şu an merkezde kırmızı var her zaman kırmızı merkez ve x ekseni olmayabilir üç nokta takibinin zararı olmaz gibi geldi.

Son durumda fonksiyonu biraz yalıttık kod şuna döndü.

import cv2 as cv
import numpy as np
import math

data = cv.imread("test.jpg")
x, y, w, h = 0, 0, 0, 0
data = cv.medianBlur(data,5)
dataHsv=cv.cvtColor(data,cv.COLOR_BGR2HSV)

a = 0
b = 0
maviDeg = None
sariDeg = None
kirmiziDeg = None
xDeg = None
yesilDeg = None

def mavi():
    global a
    global b
    global maviDeg
    mlower_color = np.array([75,100,100])#Mavi renk eşik değerleri.
    mupper_color = np.array([130,255,255])
    mask = cv.inRange(dataHsv, mlower_color,mupper_color)
    mask = cv.dilate(mask,(3,3),iterations=3)
    contour, _ = cv.findContours(mask,cv.RETR_TREE,cv.CHAIN_APPROX_SIMPLE)
    for cnt in contour:
        area = cv.contourArea(cnt)     
        if area > 480:#Kontur minimum değeri.
            x, y, w, h = cv.boundingRect(cnt) #Diktörtgen kutu çizimi.
            cv.rectangle(data, (x, y), (x + w, y + h), (0, 255, 0), 3)
            cv.putText(	data, "Mavi Hedef", (x-35,y), cv.FONT_HERSHEY_SIMPLEX, 1,(0,0,0), 2, cv.LINE_AA  )
            a = x+(w/2)  # Çerçeve genişliğinin yarısı
            b = y+(h/2)  # Çerçeve yüksekliğinin yarısı
            cv.circle(data,((int(a)),(int(b))), 1, (0,255,0), 6)
            maviDeg = ([int(a),int(b)])
            #print("mavi",a,b)

def sarı():
    global a
    global b
    global sariDeg
    slower_color = np.array([22,100,100])#Sarı renk eşik değerleri.
    supper_color = np.array([38,255,255])
    mask = cv.inRange(dataHsv, slower_color,supper_color)
    mask = cv.dilate(mask,(3,3),iterations=3)
    contour, _ = cv.findContours(mask,cv.RETR_TREE,cv.CHAIN_APPROX_SIMPLE)
    for cnt in contour:
        area = cv.contourArea(cnt)     
        if area > 480:#Kontur minimum değeri.
            x, y, w, h = cv.boundingRect(cnt) #Diktörtgen kutu çizimi.
            cv.rectangle(data, (x, y), (x + w, y + h), (0, 255, 0), 3)
            cv.putText(	data, "Sari Hedef", (x-35,y), cv.FONT_HERSHEY_SIMPLEX, 1,(0,0,0), 2, cv.LINE_AA  )
            a = x+(w/2)  # Çerçeve genişliğinin yarısı
            b = y+(h/2)  # Çerçeve yüksekliğinin yarısı
            cv.circle(data,((int(a)),(int(b))), 1, (0,255,0), 6)
            sariDeg = ([int(a),int(b)])

def yeşil():
    global a
    global b
    global yesilDeg
    ylower_color = np.array([38,100,100])#Yeşil renk eşik değerleri.
    yupper_color = np.array([75,255,255])
    mask = cv.inRange(dataHsv, ylower_color,yupper_color)
    mask = cv.dilate(mask,(3,3),iterations=3)
    contour, _ = cv.findContours(mask,cv.RETR_TREE,cv.CHAIN_APPROX_SIMPLE)
    for cnt in contour:
        area = cv.contourArea(cnt)     
        if area > 480:#Kontur minimum değeri.
            x, y, w, h = cv.boundingRect(cnt) #Diktörtgen kutu çizimi.
            cv.rectangle(data, (x, y), (x + w, y + h), (0, 255, 0), 3)
            cv.putText(	data, "Yesil Hedef", (x-35,y), cv.FONT_HERSHEY_SIMPLEX, 1,(0,0,0), 2, cv.LINE_AA  )
            a = x+(w/2)  # Çerçeve genişliğinin yarısı
            b = y+(h/2)  # Çerçeve yüksekliğinin yarısı
            cv.circle(data,((int(a)),(int(b))), 1, (0,255,0), 6)
            yesilDeg = ([int(a),int(b)])

def kırmızı():
    global kirmiziDeg
    global xDeg
    klower_color = np.array([160,100,100])#Kırrmızı renk eşik değerleri.
    kupper_color = np.array([179,255,255])
    mask = cv.inRange(dataHsv, klower_color,kupper_color)
    mask = cv.dilate(mask,(3,3),iterations=3)
    contour, _ = cv.findContours(mask,cv.RETR_TREE,cv.CHAIN_APPROX_SIMPLE)
    for cnt in contour:
        area = cv.contourArea(cnt)     
        if area > 480:#Kontur minimum değeri.
            x, y, w, h = cv.boundingRect(cnt) #Diktörtgen kutu çizimi.
            cv.rectangle(data, (x, y), (x + w, y + h), (0, 255, 0), 3)
            cv.putText(	data, "Kirmizi", (x,y), cv.FONT_HERSHEY_SIMPLEX, 1,(0,0,0), 2, cv.LINE_AA  )
            a1 = x+(w/2)  # Çerçeve genişliğinin yarısı
            b1 = y+(h/2)  # Çerçeve yüksekliğinin yarısı
            cv.circle(data,((int(a1)),(int(b1))), 1, (0,255,0), 6)
            kirmiziDeg = ([int(a1),int(b1)])
            cv.line(data, (int(a1), int(b1)), (int(a), int(b)), (0, 0, 0), 5)            
            cv.line(data, (int(a1), int(b1)), (int(a1+a1), int(b1)), (0, 0, 0), 5)
            xDeg = ([a1+a1,b1])
            

def getAngle(pointList):
    p1, p2, p3 = pointList[-3:]
    ang = math.degrees(math.atan2(p3[1]-p2[1], p3[0]-p2[0]) - math.atan2(p1[1]-p2[1], p1[0]-p2[0]))
    
    if ang < 0:
        angD= round (ang + 360)
    else: 
         angD= round(ang )
    
    return angD
    




renk = input("sarı, yeşil, mavi\nÇizgi çekilecek renk: ")
if(renk == "sarı"):
    sarı()
    kırmızı()
    spointsList =(sariDeg, kirmiziDeg, xDeg )
    
    cv.putText(data,str(getAngle(spointsList)),(kirmiziDeg[0]-40,kirmiziDeg[1]-20),cv.FONT_HERSHEY_COMPLEX,
                1.5,(0,0,255),2)
    
    cv.imshow('Resim', data)
elif(renk == "mavi"):
    mavi()
    kırmızı()
    mpointsList =(maviDeg, kirmiziDeg, xDeg )
    cv.putText(data,str(getAngle(mpointsList)),(kirmiziDeg[0]-40,kirmiziDeg[1]-20),cv.FONT_HERSHEY_COMPLEX,
                1.5,(0,0,255),2)
    
    cv.imshow('Resim', data)
elif(renk == "yeşil"):
    yeşil()
    kırmızı()
    ypointsList =(yesilDeg, kirmiziDeg, xDeg )
    cv.putText(data,str(getAngle(ypointsList)),(kirmiziDeg[0]-40,kirmiziDeg[1]-20),cv.FONT_HERSHEY_COMPLEX,
                1.5,(0,0,255),2)
    cv.imshow('Resim', data)



cv.waitKey(0)
cv.destroyAllWindows()

Dediğiniz gibi madem x sabit sadece ikinci nokta ve merkez koordinatı gönderek de yapılabilir.

EDIT:

Aklıma gelmişken bir de şu kaynağı koymak istiyorum. Her seferinde ekleyim deyip untuyorum.

python — İki nokta arasındaki açıyı (saat yönünde) hesaplayın (web-gelistirme-sc.com)

Özellikle içinde vektör öneren katılımcının çözüm tavsiyesine belki örnek olabilir diye ekleyecektim.

import math

class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y

v1 = Vector(0, 1)
v2 = Vector(0, -1)

v1_theta = math.atan2(v1.y, v1.x)
v2_theta = math.atan2(v2.y, v2.x)

r = (v2_theta - v1_theta) * (180.0 / math.pi)

if r < 0:
    r += 360.0

print r

Kodları denemedim ama mantıklı görünüyorlar.

1 Beğeni

Hocam merhabalar,
Programımızın büyük bir kısmı bitti. Şu an raspberry’yi wifi’ye bağlamaya çalışıyoruz. Ancak programda da bir sorunumuz var. Şöyleki: “resim.jpg” adlı resmi sürekli olarak içe aktarmasını istiyoruz. Bir klasöre düzenli olarak “resim.jpg” adlı bir resim gelirken bir yandan da işlediği resmi silecek ve yeni resmi içe aktaracak. Bu şekilde bir döngü oluşturmak istiyoruz.
Yazdığımız kodda belirli bir süre sonra resim gelmezse hata veriyor. Hata vermeyecek şekilde nasıl düzeltebiliriz.
Tüm kodları bırakıyorum.
Hayırlı akşamlar.

import cv2 as cv
import numpy as np
import math
import time
import serial
import os

def fotoal(): #Fotoğrafı içe aktarma.
    global data
    global dataHsv
    global fotoAd
    fotoAd = "resim5.jpg"
    data = cv.imread(fotoAd)
    x, y, w, h = 0, 0, 0, 0
    data = cv.medianBlur(data,5)
    dataHsv=cv.cvtColor(data,cv.COLOR_BGR2HSV)
    
a = 0
b = 0
maviDeg = None
sariDeg = None
kirmiziDeg = None
xDeg = None
yesilDeg = None
arduino = serial.Serial(port='COM5', baudrate=115200, timeout=.1)

def gonder(an): #Seri haberleşme.
    arduino.write(bytes(an, 'utf-8'))
    time.sleep(0.05)
    veri = arduino.readline()
    return veri
    while True:
        value = gonder(an)
        print(value)


fotoal()   
def mavi():
    global a
    global b
    global maviDeg
    mlower_color = np.array([75,100,100])#Mavi renk eşik değerleri.
    mupper_color = np.array([130,255,255])
    mask = cv.inRange(dataHsv, mlower_color,mupper_color)
    mask = cv.dilate(mask,(3,3),iterations=3)
    contour, _ = cv.findContours(mask,cv.RETR_TREE,cv.CHAIN_APPROX_SIMPLE)
    for cnt in contour:
        area = cv.contourArea(cnt)     
        if area > 480:#Kontur minimum değeri.
            x, y, w, h = cv.boundingRect(cnt) #Diktörtgen kutu çizimi.
            cv.rectangle(data, (x, y), (x + w, y + h), (0, 255, 0), 3)
            cv.putText(	data, "Mavi Hedef", (x-35,y), cv.FONT_HERSHEY_SIMPLEX, 1,(0,0,0), 2, cv.LINE_AA  )
            a = x+(w/2)  # Çerçeve genişliğinin yarısı
            b = y+(h/2)  # Çerçeve yüksekliğinin yarısı
            cv.circle(data,((int(a)),(int(b))), 1, (0,255,0), 6)
            maviDeg = ([int(a),int(b)])

def sarı():
    global a
    global b
    global sariDeg
    slower_color = np.array([22,100,100])#Sarı renk eşik değerleri.
    supper_color = np.array([38,255,255])
    mask = cv.inRange(dataHsv, slower_color,supper_color)
    mask = cv.dilate(mask,(3,3),iterations=3)
    contour, _ = cv.findContours(mask,cv.RETR_TREE,cv.CHAIN_APPROX_SIMPLE)
    for cnt in contour:
        area = cv.contourArea(cnt)     
        if area > 480:#Kontur minimum değeri.
            x, y, w, h = cv.boundingRect(cnt) #Diktörtgen kutu çizimi.
            cv.rectangle(data, (x, y), (x + w, y + h), (0, 255, 0), 3)
            cv.putText(	data, "Sari Hedef", (x-35,y), cv.FONT_HERSHEY_SIMPLEX, 1,(0,0,0), 2, cv.LINE_AA  )
            a = x+(w/2)  # Çerçeve genişliğinin yarısı
            b = y+(h/2)  # Çerçeve yüksekliğinin yarısı
            cv.circle(data,((int(a)),(int(b))), 1, (0,255,0), 6)
            sariDeg = ([int(a),int(b)])

def yeşil():
    global a
    global b
    global yesilDeg
    ylower_color = np.array([38,100,100])#Yeşil renk eşik değerleri.
    yupper_color = np.array([75,255,255])
    mask = cv.inRange(dataHsv, ylower_color,yupper_color)
    mask = cv.dilate(mask,(3,3),iterations=3)
    contour, _ = cv.findContours(mask,cv.RETR_TREE,cv.CHAIN_APPROX_SIMPLE)
    for cnt in contour:
        area = cv.contourArea(cnt)     
        if area > 480:#Kontur minimum değeri.
            x, y, w, h = cv.boundingRect(cnt) #Diktörtgen kutu çizimi.
            cv.rectangle(data, (x, y), (x + w, y + h), (0, 255, 0), 3)
            cv.putText(	data, "Yesil Hedef", (x-35,y), cv.FONT_HERSHEY_SIMPLEX, 1,(0,0,0), 2, cv.LINE_AA  )
            a = x+(w/2)  # Çerçeve genişliğinin yarısı
            b = y+(h/2)  # Çerçeve yüksekliğinin yarısı
            cv.circle(data,((int(a)),(int(b))), 1, (0,255,0), 6)
            yesilDeg = ([int(a),int(b)])

def kırmızı():
    global kirmiziDeg
    global xDeg
    klower_color = np.array([160,100,100])#Kırrmızı renk eşik değerleri.
    kupper_color = np.array([179,255,255])
    mask = cv.inRange(dataHsv, klower_color,kupper_color)
    mask = cv.dilate(mask,(3,3),iterations=3)
    contour, _ = cv.findContours(mask,cv.RETR_TREE,cv.CHAIN_APPROX_SIMPLE)
    for cnt in contour:
        area = cv.contourArea(cnt)     
        if area > 480:#Kontur minimum değeri.
            x, y, w, h = cv.boundingRect(cnt) #Diktörtgen kutu çizimi.
            cv.rectangle(data, (x, y), (x + w, y + h), (0, 255, 0), 3)
            cv.putText(	data, "Kirmizi", (x,y), cv.FONT_HERSHEY_SIMPLEX, 1,(0,0,0), 2, cv.LINE_AA  )
            a1 = x+(w/2)  # Çerçeve genişliğinin yarısı
            b1 = y+(h/2)  # Çerçeve yüksekliğinin yarısı
            cv.circle(data,((int(a1)),(int(b1))), 1, (0,255,0), 6)
            kirmiziDeg = ([int(a1),int(b1)])
            cv.line(data, (int(a1), int(b1)), (int(a), int(b)), (0, 0, 0), 5)            
            cv.line(data, (int(a1), int(b1)), (int(a1+a1), int(b1)), (0, 0, 0), 5)
            xDeg = ([a1+a1,b1])
            
angD = None
def getAngle(pointList):
    global angD
    b, a, c = pointList[-3:]
    ang = math.degrees(math.atan2(c[1]-b[1], c[0]-b[0]) - math.atan2(a[1]-b[1], a[0]-b[0]))
    
    if ang < 0:
        angD= round (ang + 360)
    else: 
         angD= round(ang )
    cv.putText(data,str(angD),(b[0]-40,b[1]-20),cv.FONT_HERSHEY_COMPLEX,1.5,(0,0,0),2)

renk = input("sarı, yeşil, mavi\nÇizgi çekilecek renk: ")
if(renk == "sarı"):
    while 1:
        try:
            sarı()
            kırmızı()
            spointsList =(kirmiziDeg,sariDeg, xDeg )
            getAngle(spointsList)
            cv.imshow('Resim', data)
            gonder(str(angD)) #Seri porttan gönder.
            print("Açı :",angD,"°",sep="")
            os.remove(fotoAd)
            fotoal()
        except:
            print("Fotoğraf bekleniyor...")
            time.sleep(10)
            fotoal()
elif(renk == "mavi"):
    mavi()
    kırmızı()
    mpointsList =(kirmiziDeg,maviDeg, xDeg )
    getAngle(mpointsList)
    gonder(str(angD)) #Seri porttan gönder.
    print("Açı :",angD,"°",sep="")
    cv.imshow('Resim', data)
elif(renk == "yeşil"):
    yeşil()
    kırmızı()
    ypointsList =(kirmiziDeg,yesilDeg, xDeg )
    getAngle(ypointsList)
    gonder(str(angD)) #Seri porttan gönder.
    print("Açı :",angD,"°",sep="")
    cv.imshow('Resim', data)





data = cv.imread(fotoAd)

Alıp alamadığınızı kontrol eden bir şeyler denemek faydalı olabilir.

Try except bloku ile alıp, hata yönetmek faydalı olabilir.

Göz ucuyla üstün körü baktım.

Deneyin takılırsanız tekrar bakablım.

Hocam en altta if’in altında dediğiniz gibi try except kullandım ama yine de foto gelmezse hata veriyor. Bahsettiğiniz gibi fotoğrafın olup olmadığını nasıl kontrol ettirebiliriz. Bu sayede foto varsa al/işle/sil yoksa bekle gibisinden bir şey yapmak istiyoruz.

Söylediğim satırı try ile kontrol edip okuma hatası varsa yeniden oku şeklinde dener misiniz?

Alt tarafta değil.

Hocam şu an Pc yanımda değil yarın deneyip sonucu sizlerle paylaşırım inşallah, hayırlı geceler dilerim.