নিকির উত্তরটি আমার সমস্যার সমাধান করেছিল, তবে তার উত্তরটি ছিল ম্যাথামেটিকায়। সুতরাং আমি ভেবেছিলাম আমার এটির ওপেনসিভি অভিযোজনটি দেওয়া উচিত। তবে প্রয়োগের পরে আমি দেখতে পেলাম যে ওপেনসিভি কোড নিকির গণিতের কোডের চেয়ে অনেক বড়। এবং এছাড়াও, আমি ওপেনসিভিতে নিকির দ্বারা করা ইন্টারপোলেশন পদ্ধতিটি খুঁজে পেলাম না (যদিও এটি স্কিপি ব্যবহার করে করা যেতে পারে, আমি সময় আসার পরে তা জানাব।)
1. চিত্র প্রাকপ্রসেসিং (বন্ধ অপারেশন)
import cv2
import numpy as np
img = cv2.imread('dave.jpg')
img = cv2.GaussianBlur(img,(5,5),0)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
mask = np.zeros((gray.shape),np.uint8)
kernel1 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(11,11))
close = cv2.morphologyEx(gray,cv2.MORPH_CLOSE,kernel1)
div = np.float32(gray)/(close)
res = np.uint8(cv2.normalize(div,div,0,255,cv2.NORM_MINMAX))
res2 = cv2.cvtColor(res,cv2.COLOR_GRAY2BGR)
ফলাফল :
২. সুডোকু স্কয়ার সন্ধান করা এবং মুখোশ চিত্র তৈরি করা
thresh = cv2.adaptiveThreshold(res,255,0,1,19,2)
contour,hier = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
max_area = 0
best_cnt = None
for cnt in contour:
area = cv2.contourArea(cnt)
if area > 1000:
if area > max_area:
max_area = area
best_cnt = cnt
cv2.drawContours(mask,[best_cnt],0,255,-1)
cv2.drawContours(mask,[best_cnt],0,0,2)
res = cv2.bitwise_and(res,mask)
ফলাফল :
3. উল্লম্ব লাইন সন্ধান করা
kernelx = cv2.getStructuringElement(cv2.MORPH_RECT,(2,10))
dx = cv2.Sobel(res,cv2.CV_16S,1,0)
dx = cv2.convertScaleAbs(dx)
cv2.normalize(dx,dx,0,255,cv2.NORM_MINMAX)
ret,close = cv2.threshold(dx,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
close = cv2.morphologyEx(close,cv2.MORPH_DILATE,kernelx,iterations = 1)
contour, hier = cv2.findContours(close,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
for cnt in contour:
x,y,w,h = cv2.boundingRect(cnt)
if h/w > 5:
cv2.drawContours(close,[cnt],0,255,-1)
else:
cv2.drawContours(close,[cnt],0,0,-1)
close = cv2.morphologyEx(close,cv2.MORPH_CLOSE,None,iterations = 2)
closex = close.copy()
ফলাফল :
অনুভূমিক রেখা সন্ধান করা
kernely = cv2.getStructuringElement(cv2.MORPH_RECT,(10,2))
dy = cv2.Sobel(res,cv2.CV_16S,0,2)
dy = cv2.convertScaleAbs(dy)
cv2.normalize(dy,dy,0,255,cv2.NORM_MINMAX)
ret,close = cv2.threshold(dy,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
close = cv2.morphologyEx(close,cv2.MORPH_DILATE,kernely)
contour, hier = cv2.findContours(close,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
for cnt in contour:
x,y,w,h = cv2.boundingRect(cnt)
if w/h > 5:
cv2.drawContours(close,[cnt],0,255,-1)
else:
cv2.drawContours(close,[cnt],0,0,-1)
close = cv2.morphologyEx(close,cv2.MORPH_DILATE,None,iterations = 2)
closey = close.copy()
ফলাফল :
অবশ্যই, এই এক এত ভাল না।
5. গ্রিড পয়েন্ট অনুসন্ধান করা
res = cv2.bitwise_and(closex,closey)
ফলাফল :
The. ত্রুটিগুলি সংশোধন করা
এখানে, নিকি একধরনের ইন্টারপোলেশন করে, যার সম্পর্কে আমার খুব বেশি জ্ঞান নেই। এবং আমি এই ওপেনসিভির জন্য কোনও সম্পর্কিত ফাংশন খুঁজে পাইনি। (এটি সেখানে থাকতে পারে, আমি জানি না)।
এই এসওএফটি পরীক্ষা করে দেখুন যা সায়পাই ব্যবহার করে এটি কীভাবে করবেন তা ব্যাখ্যা করে যা আমি ব্যবহার করতে চাই না: ওপেনসিভিতে চিত্র রূপান্তর
সুতরাং, আমি এখানে প্রতিটি উপ-বর্গক্ষেত্রের 4 টি কোণ নিয়েছি এবং প্রতিটিটিতে রেপ পরিপ্রেক্ষিত প্রয়োগ করেছি।
তার জন্য, প্রথমে আমরা সেন্ট্রয়েডগুলি সন্ধান করি।
contour, hier = cv2.findContours(res,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
centroids = []
for cnt in contour:
mom = cv2.moments(cnt)
(x,y) = int(mom['m10']/mom['m00']), int(mom['m01']/mom['m00'])
cv2.circle(img,(x,y),4,(0,255,0),-1)
centroids.append((x,y))
তবে ফলস্বরূপ সেন্ট্রয়েডগুলি বাছাই করা হবে না। তাদের অর্ডার দেখতে নীচের চিত্র দেখুন:
সুতরাং আমরা এগুলি বাম থেকে ডানে, উপরে থেকে নীচে বাছাই করি।
centroids = np.array(centroids,dtype = np.float32)
c = centroids.reshape((100,2))
c2 = c[np.argsort(c[:,1])]
b = np.vstack([c2[i*10:(i+1)*10][np.argsort(c2[i*10:(i+1)*10,0])] for i in xrange(10)])
bm = b.reshape((10,10,2))
এখন তাদের আদেশ নীচে দেখুন:
অবশেষে আমরা রূপান্তরটি প্রয়োগ করি এবং 450x450 আকারের একটি নতুন চিত্র তৈরি করি।
output = np.zeros((450,450,3),np.uint8)
for i,j in enumerate(b):
ri = i/10
ci = i%10
if ci != 9 and ri!=9:
src = bm[ri:ri+2, ci:ci+2 , :].reshape((4,2))
dst = np.array( [ [ci*50,ri*50],[(ci+1)*50-1,ri*50],[ci*50,(ri+1)*50-1],[(ci+1)*50-1,(ri+1)*50-1] ], np.float32)
retval = cv2.getPerspectiveTransform(src,dst)
warp = cv2.warpPerspective(res2,retval,(450,450))
output[ri*50:(ri+1)*50-1 , ci*50:(ci+1)*50-1] = warp[ri*50:(ri+1)*50-1 , ci*50:(ci+1)*50-1].copy()
ফলাফল :
ফলাফলটি নিকির মতো প্রায় একই, তবে কোড দৈর্ঘ্য বড়। হতে পারে, আরও ভাল পদ্ধতিগুলি সেখানে পাওয়া যায়, তবে ততক্ষণ পর্যন্ত এটি ঠিক আছে।
শুভেচ্ছা আরকে।