পাইথন ব্যবহার করে ওপেনসিভিতে কীভাবে একটি চিত্র ক্রপ করবেন


233

আমি ওপেনসিভি ব্যবহার করে যেমন পিআইএল-এর আগেও করেছি, যেমন আমি চিত্রগুলি ক্রপ করতে পারি।

পিআইএল উপর কাজ উদাহরণ

im = Image.open('0.png').convert('L')
im = im.crop((1, 1, 98, 33))
im.save('_0.png')

তবে আমি কীভাবে এটি ওপেনসিভিতে করতে পারি?

এটি আমি চেষ্টা করেছি:

im = cv.imread('0.png', cv.CV_LOAD_IMAGE_GRAYSCALE)
(thresh, im_bw) = cv.threshold(im, 128, 255, cv.THRESH_OTSU)
im = cv.getRectSubPix(im_bw, (98, 33), (1, 1))
cv.imshow('Img', im)
cv.waitKey(0)

কিন্তু এটি কাজ করে না।

আমি মনে করি আমি ভুলভাবে ব্যবহার করেছি getRectSubPix। যদি এটি হয় তবে দয়া করে ব্যাখ্যা করুন আমি কীভাবে এই ফাংশনটি সঠিকভাবে ব্যবহার করতে পারি।

উত্তর:


527

এটা খুবই সাধারণ. নপি ছাঁটাই ব্যবহার করুন।

import cv2
img = cv2.imread("lenna.png")
crop_img = img[y:y+h, x:x+w]
cv2.imshow("cropped", crop_img)
cv2.waitKey(0)

9
হুম ... তবে আমি কীভাবে ক্রপ ইমেজকে পরিবর্তনশীল হিসাবে সংরক্ষণ করতে পারি?
নোলিক

56
মনে রাখবেন যে এক্স এবং ওয়াই উল্টে গেছে আমি এটা মিস করেছি
মার্ক্রক্সোর

10
বিকল্পভাবে, আপনি যদি শস্যের মার্জিনটি সংজ্ঞায়িত করেন তবে আপনি এটি করতে পারেনcrop_img = img[margin:-margin, margin:-margin]
রুফাস

39
এটি দুর্দান্ত, কেবল সচেতন থাকুন যে ক্রপ_আইএমজি পরিবর্তন করলে ইম্জি পরিবর্তন হবে। অন্যথায়, আপনি ক্রপ_আইএমজি = ইম্জি [y: y + h, x: x + w]। কপি ()
ব্যবহারকারী 1270710

1
@ জাভাদ্ব্বা নম্পতি বাস্তবায়ন বিশদ। নম্পি কর্নের পরিবর্তে সারি, কল স্বরলিপি ব্যবহার করে, সারি
Froyo

121

আমি এই প্রশ্নটি পেয়েছি এবং এখানে আরও একটি উত্তর পেয়েছি: আগ্রহের অঞ্চল অনুলিপি করুন

আমরা যদি (0,0) চিত্রের উপরের বাম কোণ হিসাবে বাম থেকে ডানকে imএক্স দিক হিসাবে এবং শীর্ষে থেকে নীচে y দিক হিসাবে ডাকা হয় consider এবং আমাদের কাছে (x1, y1) উপরের-বাম প্রান্তিক হিসাবে এবং (x2, y2) সেই চিত্রের মধ্যে একটি আয়তক্ষেত্রের অঞ্চলের নীচের ডানদিকের ভার্টেক্স হিসাবে, তারপরে:

roi = im[y1:y2, x1:x2]

এখানে নমপি অ্যারে ইনডেক্সিং এবং স্লাইসিংয়ের একটি বিস্তৃত সংস্থান যা আপনাকে চিত্রের একটি অংশ ক্রপ করার মতো জিনিসগুলি সম্পর্কে আরও বলতে পারে। চিত্রগুলি ওপেনকভি 2-তে একটি নমপি অ্যারে হিসাবে সংরক্ষণ করা হবে।

:)


হাই, এটি কি আপনার পরিস্থিতিতে `রোই = ইম [y1: y2 + 1, x1: x2 + 1] হওয়া উচিত নয়? কারণ ন্যালি কাটা টুকরো টুকরো করা অঞ্চল ব্যবহার করে region
স্কট ইয়াং

@ সামখান 13, যখন আমি এই সূত্রটি ব্যবহার করে ক্রপ করি, তখন আমার সমস্ত ফসলের আকার (0, প্রস্থ, চ্যানেল) থাকে। অর্থাৎ। আমি মোটেও আয়তন পাচ্ছি না
mLstudent33

@ mLstudent33 সম্ভবত এটি চিত্রটি imসঠিকভাবে পড়া হয়নি এবং খালি রয়েছে। আপনার কোড ধাপে ধাপে সনাক্তকরণের জন্য ব্রেকপয়েন্ট সহ আইডিই ব্যবহার করার চেষ্টা করুন। কোড ব্লক তৈরি করতে আপনি গুগল কোলাব ব্যবহার করতে পারেন এবং কারওর সহায়তা পেতে স্ট্যাকওভারফ্লো অজগর চ্যাট রুমে আপনার বৃহত্তর নোটবুকটি ভাগ করতে পারেন।
samkhan13

@ সামখান 13 আসলে আমি একটি অদ্ভুত ইস্যু পেয়েছি যা আমি গিথুব ওপেনসিভি ইস্যুতে পোস্ট করেছি: github.com/opencv/opencv/issues/15406 আমিও আড্ডা চেক করব। ধন্যবাদ!
mLstudent33

16

মনে রাখবেন, চিত্র স্লাইসিং এর অনুলিপি তৈরি করে না তবে একটিতে একটি cropped imageতৈরি pointerকরছে roi। যদি আপনি এতগুলি চিত্র লোড করে থাকেন, কাটা দিয়ে ছবিগুলির প্রাসঙ্গিক অংশগুলি কাটাচ্ছেন, তবে একটি তালিকায় যুক্ত করুন, এটি একটি বিশাল মেমরির অপচয় হতে পারে।

মনে করুন আপনি প্রতিটি এন এন চিত্র লোড করেছেন >1MPএবং 100x100উপরের বাম কোণে আপনার কেবল অঞ্চল দরকার ।

Slicing:

X = []
for i in range(N):
    im = imread('image_i')
    X.append(im[0:100,0:100]) # This will keep all N images in the memory. 
                              # Because they are still used.

বিকল্পভাবে, আপনি প্রাসঙ্গিক অংশটি এর দ্বারা অনুলিপি করতে পারেন .copy(), তাই আবর্জনা সংগ্রহকারী সরিয়ে ফেলবে im

X = []
for i in range(N):
    im = imread('image_i')
    X.append(im[0:100,0:100].copy()) # This will keep only the crops in the memory. 
                                     # im's will be deleted by gc.

এই আউট খোঁজার পর, আমি বুঝতে পেরেছি মন্তব্য এক দ্বারা user1270710 যে উল্লেখ কিন্তু এটা আমার খুঁজে বের করতে (অর্থাত, ডিবাগিং ইত্যাদি) বেশ কিছু সময়ের নেন। সুতরাং, আমি মনে করি এটি উল্লেখ করা মূল্যবান।



মেমরির জায়গা দখল করার অর্থ, আমি বুঝতে পারি যে আগ্রহের অঞ্চলটি অনুলিপি করা সবচেয়ে ভাল কাজ, তবে সময় সাপেক্ষে কী হবে? আমি যদি copy()কাঁচের তুলনায় আরওআই করি তবে ফলাফল কী হবে? এছাড়াও, আমার যদি একটি পরিবর্তনশীল tmpথাকে যেখানে আমি আমার কম্পিউটার থেকে লোড করা প্রতিটি ছবি সঞ্চয় করি, স্লাইসিংয়ের ফলে আমার স্মৃতিতে খারাপ প্রভাব ফেলতে হবে না, তাই না? আপনি যে সমস্যাটি বর্ণনা করেছেন তা কেবল তখনই সম্পর্কিত যা আপনি যখন সমস্ত চিত্র লোড করেন এবং তারপরে আপনি তাদের আরওআইআই সংরক্ষণ করেন, মূল এবং আরওআই উভয়ই রাখেনআমি সঠিক বুঝতে পারছিলাম কিনা দয়া করে আমাকে জানান।
ক্যাটালিনা সরবু

আমি বললাম যে ক্ষেত্রে কপি করা নগণ্য সময় হবে। আপনি যদি এত বড় বারের চিত্রগুলি অনুলিপি না করেন তবে আপনার সময়ের পার্থক্য থাকবে না। আমার কোডে, প্রভাবটি প্রতি ফসল প্রতি 1 মিমের চেয়ে কম হবে। সমস্যাটি হ'ল আপনি হয় বড় চিত্র এবং পয়েন্টার (আরওআই যা কেবলমাত্র কয়েকটি বাইট) সংরক্ষণ করেন বা আপনি মেমরিতে একটি ছোট চিত্র সঞ্চয় করেন (আমার ক্ষেত্রে)। আপনি যদি কয়েকবার এটি করেন তবে তা ঠিক আছে। তবে আপনি যদি হাজার হাজার বার এটি করেন তবে মেমরির ব্যবহার স্লাইস করে পাগল হবে। আপনি কয়েক স্লোগান লোকে লোড করলে হাজার মেমরি লোড হয়ে গেলে পুরো মেমোরিটি পূরণ করুন। আমার
কোডগুলি

12

এই কোডটি x = 0, y = 0 অবস্থান থেকে h = 100, ডাব্লু = 200 এ কোনও চিত্র কাটাবে

import numpy as np
import cv2

image = cv2.imread('download.jpg')
y=0
x=0
h=100
w=200
crop = image[y:y+h, x:x+w]
cv2.imshow('Image', crop)
cv2.waitKey(0) 

@ হট্টি, সুতরাং উচ্চতা 100 পিক্সেল নীচে "y = 0 ডান? এটি কি নিমপী অ্যারের 101 তম সারিতে? এবং প্রস্থটি x = 0 এর ডান থেকে 200 পিক্সেল সঠিক?
mLstudent33

4

নীচে একটি চিত্র ক্রপ করার উপায় রয়েছে।

চিত্র_পথ: সম্পাদনা করার জন্য চিত্রের পথ

কর্ডগুলি: এক্স / ওয়াই কোঅর্ডিনেটের একটি টিপল (x1, y1, x2, y2) [চিত্রটি এমস্পেন্টে খুলুন এবং স্থানাঙ্কগুলি দেখতে ভিউ ট্যাবে "রুলার" চেক করুন]

সেভড_লোকেশন : ক্রপড ইমেজ সংরক্ষণের পাথ

from PIL import Image
    def crop(image_path, coords, saved_location:
        image_obj = Image.open("Path of the image to be cropped")
            cropped_image = image_obj.crop(coords)
            cropped_image.save(saved_location)
            cropped_image.show()


if __name__ == '__main__':
    image = "image.jpg"
    crop(image, (100, 210, 710,380 ), 'cropped.jpg')

3

ওপেনসিভি অনুলিপি সীমানা ফাংশন সহ শক্তিশালী ফসল:

def imcrop(img, bbox):
   x1, y1, x2, y2 = bbox
   if x1 < 0 or y1 < 0 or x2 > img.shape[1] or y2 > img.shape[0]:
        img, x1, x2, y1, y2 = pad_img_to_fit_bbox(img, x1, x2, y1, y2)
   return img[y1:y2, x1:x2, :]

def pad_img_to_fit_bbox(img, x1, x2, y1, y2):
    img = cv2.copyMakeBorder(img, - min(0, y1), max(y2 - img.shape[0], 0),
                            -min(0, x1), max(x2 - img.shape[1], 0),cv2.BORDER_REPLICATE)
   y2 += -min(0, y1)
   y1 += -min(0, y1)
   x2 += -min(0, x1)
   x1 += -min(0, x1)
   return img, x1, x2, y1, y2

আপনি কি দয়া করে এখানে ববক্স কী এবং আমাদের এর মানটি কী দিতে হবে তা ব্যাখ্যা করতে পারেন কারণ আমি যে মানটিই পাস করার চেষ্টা করছি তা x1,y1,x2,y2 = bbox বলার সময় এটি আমাকে ত্রুটি দিচ্ছে :TypeError: 'int' object is not iterable
সাবাহ

3

এখানে আরও শক্তিশালী ইমক্রপ করার জন্য কিছু কোড রয়েছে (মতলব-এর মতো)

def imcrop(img, bbox): 
    x1,y1,x2,y2 = bbox
    if x1 < 0 or y1 < 0 or x2 > img.shape[1] or y2 > img.shape[0]:
        img, x1, x2, y1, y2 = pad_img_to_fit_bbox(img, x1, x2, y1, y2)
    return img[y1:y2, x1:x2, :]

def pad_img_to_fit_bbox(img, x1, x2, y1, y2):
    img = np.pad(img, ((np.abs(np.minimum(0, y1)), np.maximum(y2 - img.shape[0], 0)),
               (np.abs(np.minimum(0, x1)), np.maximum(x2 - img.shape[1], 0)), (0,0)), mode="constant")
    y1 += np.abs(np.minimum(0, y1))
    y2 += np.abs(np.minimum(0, y1))
    x1 += np.abs(np.minimum(0, x1))
    x2 += np.abs(np.minimum(0, x1))
    return img, x1, x2, y1, y2

1

বিকল্পভাবে, আপনি ফসলের জন্য টেনসরফ্লো এবং চিত্র থেকে একটি অ্যারে তৈরি করতে ওপেনসিভি ব্যবহার করতে পারেন।

import cv2
img = cv2.imread('YOURIMAGE.png')

এখন imgএকটি (চিত্রের উচ্চতা, চিত্রের দৈর্ঘ্য, 3) আকারের অ্যারে। টেনসরফ্লো দিয়ে অ্যারে ক্রপ করুন:

import tensorflow as tf
offset_height=0
offset_width=0
target_height=500
target_width=500
x = tf.image.crop_to_bounding_box(
    img, offset_height, offset_width, target_height, target_width
)

Tf.keras দিয়ে চিত্রটি পুনরায় সংশ্লেষ করুন, যাতে এটি কাজ করে তবে আমরা এটি দেখতে পারি:

tf.keras.preprocessing.image.array_to_img(
    x, data_format=None, scale=True, dtype=None
)

এটি একটি নোটবুকের মধ্যে পিকটি ছাপিয়েছে (গুগল কোলাবে পরীক্ষিত)।


পুরো কোড একসাথে:

import cv2
img = cv2.imread('YOURIMAGE.png')

import tensorflow as tf
offset_height=0
offset_width=0
target_height=500
target_width=500
x = tf.image.crop_to_bounding_box(
    img, offset_height, offset_width, target_height, target_width
)

tf.keras.preprocessing.image.array_to_img(
    x, data_format=None, scale=True, dtype=None
)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.