1. 程式人生 > 其它 >OpenCV筆記

OpenCV筆記

使用OpenCV進行讀/寫/展示圖片

總覽

Python

# import the cv2 library
import cv2

# The function cv2.imread() is used to read an image.
img_grayscale = cv2.imread('test.jpg',0)

# The function cv2.imshow() is used to display an image in a window.
cv2.imshow('graycsale image',img_grayscale)

# waitKey() waits for a key press to close the window and 0 specifies indefinite loop
cv2.waitKey(0)

# cv2.destroyAllWindows() simply destroys all the windows we created.
cv2.destroyAllWindows()

# The function cv2.imwrite() is used to write an image.
cv2.imwrite('grayscale.jpg',img_grayscale)

C++

//Include Libraries
#include<opencv2/opencv.hpp>
#include<iostream>

// Namespace nullifies the use of cv::function(); 
using namespace std;
using namespace cv;

// Read an image 
Mat img_grayscale = imread("test.jpg", 0);

// Display the image.
imshow("grayscale image", img_grayscale);  // 無需在他們的前面加上名稱空間,例如cv::imshow()

// Wait for a keystroke.   
waitKey(0);  

// Destroys all the windows created                         
destroyAllWindows();

// Write the image in the same directory
imwrite("grayscale.jpg", img_grayscale);

1. imread() 讀取圖片

  • 語法imread(filename, flags)

    第一個引數: 影象名
    第二個引數:[optional flag]
    	cv2.IMREAD_UNCHANGED  or -1
    	cv2.IMREAD_GRAYSCALE  or 0
    	cv2.IMREAD_COLOR  or 1  # 這個是預設值,讀取圖片作為彩色圖片
    
  • 注意:

    OpenCV讀取出來的是BGR格式,但是其他cv庫使用的是RGB格式(所以有時候需要轉換格式)
    例如:
    from matplotlib import pyplot as plt
    plt.axis("off")
    plt.imshow(cv2.cvtColor(img_color, cv2.COLOR_BGR2RGB))
    plt.show()
    

2. imshow() 在視窗展示圖片

  • 語法imshow(window_name, image)

    第一個引數是視窗名
    第二個是需要展示的圖片
    
    要一次顯示多個影象,請為要顯示的每個影象指定一個新視窗名稱。
    該函式一般和waitKey(),destroyAllWindows() / destroyWindow()一起使用
    waitKey()是鍵盤響應函式,它需要一個引數: 顯示視窗的時間(單位毫秒),如果是0則無限期等待擊鍵。
    還可以設定該功能以檢測鍵盤上的 Q 鍵或 ESC 鍵等特定擊鍵,從而更明確地告訴哪個鍵應該觸發哪個行為
    
  • 案例

    Python

    #Displays image inside a window
    cv2.imshow('color image',img_color)  
    cv2.imshow('grayscale image',img_grayscale)
    cv2.imshow('unchanged image',img_unchanged)
    
    # Waits for a keystroke
    cv2.waitKey(0)  # 0表示一直等待,也可以填具體時間單位是毫秒。可以通過返回值來判斷是q or ESC
    
    # Destroys all the windows created
    cv2.destroyAllwindows() 
    

    C++

    // Create a window.
    namedWindow( "color image", WINDOW_AUTOSIZE );
    namedWindow( "grayscale image", WINDOW_AUTOSIZE );
    namedWindow( "unchanged image", WINDOW_AUTOSIZE );
    
    // Show the image inside it.
    imshow( "color image", img_color ); 
    imshow( "grayscale image", img_grayscale );
    imshow( "unchanged image", img_unchanged ); 
    
    // Wait for a keystroke.   
    waitKey(0);  
    
    // Destroys all the windows created                         
    destroyAllWindows();
    

3. imwrite() 寫檔案到檔案目錄

  • 語法imwrite(filename, image)

    第一個引數是檔名,必須包括副檔名(.png, .jpg etc)
    第二個引數是儲存的圖片,如果儲存成功返回True
    
  • 案例

Python

cv2.imwrite('grayscale.jpg',img_grayscale)

C++

imwrite("grayscale.jpg", img_grayscale);

使用OpenCV讀/寫視訊

1. Reading Videos

part1: Reading Video From a file

Python

import cv2 

# Create a video capture object, in this case we are reading the video from a file
vid_capture = cv2.VideoCapture('Resources/Cars.mp4')  # 建立一個視訊捕捉物件,有助於流式傳輸或顯示視訊

if (vid_capture.isOpened() == False):  # isOpened()方法判斷視訊檔案是否開啟正確
	print("Error opening the video file")
# Read fps and frame count
else:
	# Get frame rate information
	# You can replace 5 with CAP_PROP_FPS as well, they are enumerations
	fps = vid_capture.get(5)  # get() 方法得到視訊流的元資料,注意該方法不適合web cameras.# 5代表frame rate(幀率fps)
	print('Frames per second : ', fps,'FPS')

	# Get frame count
	# You can replace 7 with CAP_PROP_FRAME_COUNT as well, they are enumerations
	frame_count = vid_capture.get(7)  # 7代表幀數(frame count)
	print('Frame count : ', frame_count)

while(vid_capture.isOpened()):
	# vid_capture.read() methods returns a tuple, first element is a bool 
	# and the second is frame
    # 一幀一幀的讀取
	ret, frame = vid_capture.read()  # read()放回元組,第一個是boolean[True表示視訊流包含要讀取的幀], 第二個是實際的視訊幀
	if ret == True:
		cv2.imshow('Frame',frame)
		# 20 is in milliseconds, try to increase the value, say 50 and observe
		key = cv2.waitKey(20)
		
		if key == ord('q'):
			break
	else:
		break

# Release the video capture object
vid_capture.release()  # 釋放視訊捕捉物件
cv2.destroyAllWindows()  # 關閉所有視窗

C++

// Include Libraries
#include<opencv2/opencv.hpp>
#include<iostream>

// Namespace to nullify use of cv::function(); syntax
using namespace std;
using namespace cv;

int main()
{
	// initialize a video capture object
	VideoCapture vid_capture("Resources/Cars.mp4");

	// Print error message if the stream is invalid
	if (!vid_capture.isOpened())
	{
		cout << "Error opening video stream or file" << endl;
	}

	else
	{
		// Obtain fps and frame count by get() method and print
		// You can replace 5 with CAP_PROP_FPS as well, they are enumerations
		int fps = vid_capture.get(5);
		cout << "Frames per second :" << fps;

		// Obtain frame_count using opencv built in frame count reading method
		// You can replace 7 with CAP_PROP_FRAME_COUNT as well, they are enumerations
		int frame_count = vid_capture.get(7);
		cout << "  Frame count :" << frame_count;
	}


	// Read the frames to the last frame
	while (vid_capture.isOpened())
	{
		// Initialise frame matrix
		Mat frame;

	    // Initialize a boolean to check if frames are there or not
		bool isSuccess = vid_capture.read(frame);

		// If frames are present, show it
		if(isSuccess == true)
		{
			//display frames
			imshow("Frame", frame);
		}

		// If frames are not there, close it
		if (isSuccess == false)
		{
			cout << "Video camera is disconnected" << endl;
			break;
		}
		
		//wait 20 ms between successive frames and break the loop if key q is pressed
		int key = waitKey(20);
		if (key == 'q')
		{
			cout << "q key is pressed by the user. Stopping the video" << endl;
			break;
		}


	}
	// Release the video capture object
	vid_capture.release();
	destroyAllWindows();
	return 0;
}

Part2: Reading an Image Sequence

Python

vid_capture = cv2.VideoCapture('Resources/Image_sequence/Cars%04d.jpg')

C++

VideoCapture vid_capture("Resources/Image_sequence/Cars%04d.jpg");
+ 注意: 該資料的形式是: (Race_Cars_01.jpg, Race_Cars_02.jpg, Race_Cars_03.jpg, etc…)

Part3: Reading Video from a Webcam(攝像頭)

  • 如果是系統內建的攝像頭,裝置的索引可以寫成0
  • 如果系統連線多個攝像頭,索引可以增加(e.g. 1, 2, etc)

Python

vid_capture = cv2.VideoCapture(0, cv2.CAP_DSHOW)  # CAP_DSHOW是一個可選項,通過視訊輸入直接顯示的縮寫

C++

VideoCapture vid_capture(0);

2. Writing videos

預覽

import cv2

vid_capture = cv2.VideoCapture("video/test.mp4")

frame_width = int(vid_capture.get(3))
frame_height = int(vid_capture.get(4))
frame_size = (frame_width, frame_height)

output = cv2.VideoWriter("video/out_video.avi",
                         cv2.VideoWriter_fourcc('M','J','P','G'),
                         20,
                         frame_size
                         )
while(vid_capture.isOpened()):
    ret, frame = vid_capture.read()
    if ret == True:
        output.write(frame)
    else:
        print("Stream disconnected")
        break

vid_capture.release()
output.release()
  • 前置知識: 獲取視訊幀的width和height

Python

# Obtain frame size information using get() method
frame_width = int(vid_capture.get(3))
frame_height = int(vid_capture.get(4))
frame_size = (frame_width,frame_height)
fps = 20

C++

// Obtain frame size information using get() method
Int frame_width = static_cast<int>(vid_capture.get(3));
int frame_height = static_cast<int>(vid_capture.get(4));
Size frame_size(frame_width, frame_height);
int fps = 20;
  • 語法: VideoWriter(filename, apiPreference, fourcc, fps, frameSize[, isColor])
filename: 輸出檔案的路徑
apiPreference: API後端識別符號
fourcc: 編解碼器的 4 字元程式碼,用於壓縮幀
fps: 建立的視訊流的幀率
fram_size: 視訊幀的大小
isCOlor: 如果不為零,編碼器將期望並編碼彩色幀。 否則它將適用於灰度幀(該標誌目前僅在 Windows 上受支援)
  • 一個特殊的便利函式用於檢索四字元編解碼器,需要作為視訊寫入器物件 cv2 的第二個引數

    • VideoWriter_fourcc('M', 'J', 'P', 'G') in Python.
    • VideoWriter::fourcc('M', 'J', 'P', 'G') in C++.
  • 視訊編解碼器指定如何壓縮視訊流。 它將未壓縮的視訊轉換為壓縮格式,反之亦然。 要建立 AVI 或 MP4 格式,請使用以下fourcc規範

    • AVI: cv2.VideoWriter_fourcc('M','J','P','G')
    • MP4: cv2.VideoWriter_fourcc(*'XVID')

Python

# Initialize video writer object
output = cv2.VideoWriter('Resources/output_video_from_file.avi', cv2.VideoWriter_fourcc('M','J','P','G'), 20, frame_size)

C++

//Initialize video writer object
VideoWriter output("Resources/output.avi", VideoWriter::fourcc('M', 'J', 'P', 'G'),frames_per_second, frame_size);
  • 下面以每秒 20 幀的速度將 AVI 視訊檔案寫入磁碟

Python

while(vid_capture.isOpened()):
    # vid_capture.read() methods returns a tuple, first element is a bool 
    # and the second is frame

    ret, frame = vid_capture.read()
    if ret == True:
           # Write the frame to the output files
           output.write(frame)
    else:
         print(‘Stream disconnected’)
           break

C++

while (vid_capture.isOpened())
{
        // Initialize frame matrix
        Mat frame;

          // Initialize a boolean to check if frames are there or not
        bool isSuccess = vid_capture.read(frame);

        // If frames are not there, close it
        if (isSuccess == false)
        {
            cout << "Stream disconnected" << endl;
            break;
        }


            // If frames are present
        if(isSuccess == true)
        {
            //display frames
            output.write(frame);
                  // display frames
                  imshow("Frame", frame);

                  // wait for 20 ms between successive frames and break        
                  // the loop if key q is pressed
                  int key = waitKey(20);
                  if (key == ‘q’)
                  {
                      cout << "Key q key is pressed by the user. 
                      Stopping the video" << endl;
                      break;
                  }
        }
 }
  • 最後,釋放video capture和video-writer

Python

# Release the objects
vid_capture.release()
output.release()

C++

// Release the objects
vid_capture.release();
output.release();

使用OpenCV進行標註圖片

  • 在圖片中新增資訊
  • 在物件檢測的情況下在物件周圍繪製邊界框
  • 用不同顏色突出顯示畫素以進行影象分割

用彩色線條標註影象

  • 語法 line(image, start_point, end_point, color, thickness)

Python

# Import dependencies
import cv2
# Read Images
img = cv2.imread('sample.jpg')
# Display Image
cv2.imshow('Original Image',img)
cv2.waitKey(0)
# Print error message if image is null
if img is None:
    print('Could not read image')
# Draw line on image
imageLine = img.copy()  # 進行拷貝圖片
# Draw the image from point A to B
pointA = (200,80)
pointB = (450,80)
# 左上角是原始的點,x 軸代表影象的水平方向 y軸代表影象的垂直方向
# 其中imageLine是原始的圖片, 開始點,結束點,線條的顏色,線條粗細,
cv2.line(imageLine, pointA, pointB, (255, 255, 0), thickness=3, lineType=cv2.LINE_AA)
cv2.imshow('Image Line', imageLine)
cv2.waitKey(0)

C++

// Import dependencies
#include <opencv2/opencv.hpp>
#include <iostream>
// Using namespaces to nullify use of c::function(); syntax and std::function(); syntax
using namespace std;
using namespace cv;
int main()
{
    // Read Images
    Mat img = imread("sample.jpg");
    // Display Image
    imshow("Original Image", img);
    waitKey();
    // Print Error message if image is null
    if (img.empty())
        {
            cout << "Could not read image" << endl;
        }
    // Draw line on image
    Mat imageLine = img.clone();  // 進行拷貝圖片
    Point pointA(200,80);
    Point pointB(450,80);
    line(imageLine, pointA, pointB, Scalar(255, 255, 0), 3, 8, 0);
    imshow("Lined Image", imageLine);
    waitKey();
}

畫個圓

  • 語法: circle(image, center_coordinates, radius, color, thickness)
    • 引數分別是圖片,中心點,半徑,顏色,線條粗細

Python

# Make a copy of image
imageCircle = img.copy()
# define the center of circle
circle_center = (415,190)
# define the radius of the circle
radius =100
#  Draw a circle using the circle() Function
cv2.circle(imageCircle, circle_center, radius, (0, 0, 255), thickness=3, lineType=cv2.LINE_AA) 
# Display the result
cv2.imshow("Image Circle",imageCircle)
cv2.waitKey(0)

C++

// Make a copy of image
Mat circle_image = img.clone();
// define the center of circle
Point circle_center(415,190);
// define the radius of circle
int radius = 100;
// Draw a circle using the circle() Function
circle(circle_image, circle_center, radius, Scalar(0, 0, 255), 3, 8, 0);
// Display the result
imshow("Circle on Image", circle_image);
waitKey();

畫個實心圓

Python

# make a copy of the original image
imageFilledCircle = img.copy()
# define center of the circle 
circle_center = (415,190)
# define the radius of the circle
radius =100
# draw the filled circle on input image (這裡thickness=-1表示畫實心圓)
cv2.circle(imageFilledCircle, circle_center, radius, (255, 0, 0), thickness=-1, lineType=cv2.LINE_AA)
# display the output image 
cv2.imshow('Image with Filled Circle',imageFilledCircle)
cv2.waitKey(0)

C++

// make a copy of the original image
Mat Filled_circle_image = img.clone();
// define the center of circle
Point circle_center(415,190);
// define the radius of the circle
int radius = 100;
//Draw a Filled Circle using the circle() Function
circle(Filled_circle_image, circle_center, radius, Scalar(255, 0, 0), -1, 8, 0);
// display the output image
imshow("Circle on Image", circle_image);
waitKey();

畫一個矩形

  • 語法: rectangle(image, start_point, end_point, color, thickness)
    • start_point: (top, left) end_point: (bottom, right)

Python

# make a copy of the original image
imageRectangle = img.copy()
# define the starting and end points of the rectangle
start_point =(300,115)
end_point =(475,225)
# draw the rectangle
cv2.rectangle(imageRectangle, start_point, end_point, (0, 0, 255), thickness= 3, lineType=cv2.LINE_8) 
# display the output
cv2.imshow('imageRectangle', imageRectangle)
cv2.waitKey(0)

C++

// make a copy of the original image
Mat rect_image = image.clone();
// Define the starting and end points for the rectangle
Point start_point(300,115);
Point end_point(475,225);
// Draw a rectangle using the rectangle() function
rectangle(rect_image, start_point, end_point, Scalar(0,0,255), 3, 8, 0);
imshow("Rectangle on Image", rect_image);
waitKey();

新增文字

  • 語法: putText(image, text, org, font, fontScale, color)
    • image: 原始圖片 text: 需要標註的文字
    • org: 文字處在的(top, left)座標
    • fontFace: OpenCV 支援 Hershey 字型集合中的幾種字型樣式,以及斜體字型。 如下:
      • FONT_HERSHEY_SIMPLEX = 0,
      • FONT_HERSHEY_PLAIN = 1,
      • FONT_HERSHEY_DUPLEX = 2,
      • FONT_HERSHEY_COMPLEX = 3,
      • FONT_HERSHEY_TRIPLEX = 4,
      • FONT_HERSHEY_COMPLEX_SMALL = 5,
      • FONT_HERSHEY_SCRIPT_SIMPLEX = 6,
      • FONT_HERSHEY_SCRIPT_COMPLEX = 7,
      • FONT_ITALIC = 16
    • fontScale: 字型比例是一個浮點值,用於向上或向下縮放字型的基本大小。 根據影象的解析度,選擇適當的字型比例。
    • color: 這裡是一個BGR元組(B, G, R)

Python

# make a copy of the original image
imageText = img.copy()
#let's write the text you want to put on the image
text = 'I am a Happy dog!'
#org: Where you want to put the text
org = (50,350)
# write the text on the input image
# 原始圖片 文字 左上角 字型樣式 字型縮放比例 字型顏色
cv2.putText(imageText, text, org, fontFace=cv2.FONT_HERSHEY_COMPLEX, fontScale=1.5, color=(250,225,100))

# display the output image with text over it
cv2.imshow("Image Text",imageText)
cv2.waitKey(0)
cv2.destroyAllWindows()

C++

// make a copy of the original image
Mat imageText = img.clone();
// Write text using putText() function
putText(imageText, "I am a Happy dog!", Point(50,350), FONT_HERSHEY_COMPLEX, 1.5, Scalar(250,225,100));
imshow("Text on Image", imageText);
waitKey(0);

使用OpenCV進行縮放圖片

  • 在調整大小的影象中也保持相同,請務必記住影象的原始縱橫比(即寬度與高度)。

  • 減小影象的大小將需要對畫素進行重新取樣。

  • 增加影象的大小需要重建影象。 這意味著您需要插入新畫素。(可以使用影象插值技術)

Image resizing with a custom Width and Height

Python

# let's start with the Imports 
import cv2
import numpy as np

# Read the image using imread function
image = cv2.imread('image.jpg')
cv2.imshow('Original Image', image)

# let's downscale the image using new  width and height
down_width = 300  # 可以通過h,w,c=image.shape返回圖片height,wight, number of channels
down_height = 200
down_points = (down_width, down_height)
resized_down = cv2.resize(image, down_points, interpolation= cv2.INTER_LINEAR)

# let's upscale the image using new  width and height
up_width = 600
up_height = 400
up_points = (up_width, up_height)
resized_up = cv2.resize(image, up_points, interpolation= cv2.INTER_LINEAR)

# Display images
cv2.imshow('Resized Down by defining height and width', resized_down)
cv2.waitKey()
cv2.imshow('Resized Up image by defining height and width', resized_up)
cv2.waitKey()

#press any key to close the windows
cv2.destroyAllWindows()

C++

// let's start with including libraries 
#include<opencv2/opencv.hpp>
#include<iostream>

// Namespace to nullify use of cv::function(); syntax
using namespace std;
using namespace cv;

int main()
{
	// Read the image using imread function
	Mat image = imread("image.jpg");
	imshow("Original Image", image);


	// let's downscale the image using new  width and height
	int down_width = 300;
	int down_height = 200;
	Mat resized_down;
	//resize down
	resize(image, resized_down, Size(down_width, down_height), INTER_LINEAR);
	// let's upscale the image using new  width and height
	int up_width = 600;
	int up_height = 400;
	Mat resized_up;
	//resize up
	resize(image, resized_up, Size(up_width, up_height), INTER_LINEAR);
	// Display Images and press any key to continue
	imshow("Resized Down by defining height and width", resized_down);
	waitKey();
	imshow("Resized Up image by defining height and width", resized_up);
	waitKey();


	destroyAllWindows();
	return 0;
}

Resizing an image with a Scaling factor

  • INTER_AREA : 使用畫素區域關係進行重取樣。 這最適合減小影象的大小(縮小)。 當用於放大影象時,它使用 INTER_NEAREST 方法。
  • INTER_CUBIC: 這使用雙三次插值來調整影象大小。 在調整大小和插入新畫素時,此方法作用於影象的 4×4 相鄰畫素。 然後取 16 個畫素的權重平均值來建立新的插值畫素。
  • INTER_LINEAR: 這種方法有點類似於 INTER_CUBIC 插值。 但與 INTER_CUBIC 不同,它使用 2×2 相鄰畫素來獲得插值畫素的加權平均值。
  • INTER_NEAREST: INTER_NEAREST 方法使用最近鄰概念進行插值。 這是最簡單的方法之一,僅使用影象中的一個相鄰畫素進行插值。

Python

# Scaling Down the image 0.6 times using different Interpolation Method
res_inter_nearest = cv2.resize(image, None, fx= scale_down, fy= scale_down, interpolation= cv2.INTER_NEAREST)
res_inter_linear = cv2.resize(image, None, fx= scale_down, fy= scale_down, interpolation= cv2.INTER_LINEAR)
res_inter_area = cv2.resize(image, None, fx= scale_down, fy= scale_down, interpolation= cv2.INTER_AREA)

# Concatenate images in horizontal axis for comparison
vertical= np.concatenate((res_inter_nearest, res_inter_linear, res_inter_area), axis = 0)
# Display the image Press any key to continue
cv2.imshow('Inter Nearest :: Inter Linear :: Inter Area', vertical)

C++

# Scaling Down the image 0.6 using different Interpolation Method
Mat res_inter_linear, res_inter_nearest, res_inter_area;
resize(image, res_inter_linear, Size(), scale_down, scale_down, INTER_LINEAR);
resize(image, res_inter_nearest, Size(), scale_down, scale_down, INTER_NEAREST);
resize(image, res_inter_area, Size(), scale_down, scale_down, INTER_AREA);

Mat a,b,c;
vconcat(res_inter_linear, res_inter_nearest, a);
vconcat(res_inter_area, res_inter_area, b);
vconcat(a, b, c);
// Display the image Press any key to continue
imshow("Inter Linear :: Inter Nearest :: Inter Area :: Inter Area", c);

使用OpenCV裁剪圖片

Cropping using OpenCV

Python

# Import packages
import cv2
import numpy as np

img = cv2.imread('test.jpg')
print(img.shape) # Print image shape
cv2.imshow("original", img)

# Cropping an image  cropped=img[start_row:end_row, start_col:end_col]
cropped_image = img[80:280, 150:330]

# Display cropped image
cv2.imshow("cropped", cropped_image)

# Save the cropped image
cv2.imwrite("Cropped Image.jpg", cropped_image)

cv2.waitKey(0)
cv2.destroyAllWindows()

C++

// Include Libraries
#include<opencv2/opencv.hpp>
#include<iostream>

// Namespace nullifies the use of cv::function();
using namespace std;
using namespace cv;

int main()
{
	// Read image
	Mat img = imread("test.jpg");
	cout << "Width : " << img.size().width << endl;
	cout << "Height: " << img.size().height << endl;
	cout<<"Channels: :"<< img.channels() << endl;
	// Crop image
	Mat cropped_image = img(Range(80,280), Range(150,330));

	//display image
	imshow(" Original Image", img);
	imshow("Cropped Image", cropped_image);

	//Save the cropped Image
	imwrite("Cropped Image.jpg", cropped_image);

	// 0 means loop infinitely
	waitKey(0);
	destroyAllWindows();
	return 0;
}

Diving an Image into Small Patches

Python

img =  cv2.imread("test_cropped.jpg")
image_copy = img.copy() 
imgheight=img.shape[0]
imgwidth=img.shape[1]

M = 76
N = 104
x1 = 0
y1 = 0

for y in range(0, imgheight, M):
    for x in range(0, imgwidth, N):
        if (imgheight - y) < M or (imgwidth - x) < N:
            break
            
        y1 = y + M
        x1 = x + N

        # check whether the patch width or height exceeds the image width or height
        if x1 >= imgwidth and y1 >= imgheight:
            x1 = imgwidth - 1
            y1 = imgheight - 1
            #Crop into patches of size MxN
            tiles = image_copy[y:y+M, x:x+N]
            #Save each patch into file directory
            cv2.imwrite('saved_patches/'+'tile'+str(x)+'_'+str(y)+'.jpg', tiles)
            cv2.rectangle(img, (x, y), (x1, y1), (0, 255, 0), 1)
        elif y1 >= imgheight: # when patch height exceeds the image height
            y1 = imgheight - 1
            #Crop into patches of size MxN
            tiles = image_copy[y:y+M, x:x+N]
            #Save each patch into file directory
            cv2.imwrite('saved_patches/'+'tile'+str(x)+'_'+str(y)+'.jpg', tiles)
            cv2.rectangle(img, (x, y), (x1, y1), (0, 255, 0), 1)
        elif x1 >= imgwidth: # when patch width exceeds the image width
            x1 = imgwidth - 1
            #Crop into patches of size MxN
            tiles = image_copy[y:y+M, x:x+N]
            #Save each patch into file directory
            cv2.imwrite('saved_patches/'+'tile'+str(x)+'_'+str(y)+'.jpg', tiles)
            cv2.rectangle(img, (x, y), (x1, y1), (0, 255, 0), 1)
        else:
            #Crop into patches of size MxN
            tiles = image_copy[y:y+M, x:x+N]
            #Save each patch into file directory
            cv2.imwrite('saved_patches/'+'tile'+str(x)+'_'+str(y)+'.jpg', tiles)
            cv2.rectangle(img, (x, y), (x1, y1), (0, 255, 0), 1)
   
#Save full image into file directory
cv2.imshow("Patched Image",img)
cv2.imwrite("patched.jpg",img)
 
cv2.waitKey()
cv2.destroyAllWindows()

C++

Mat img = imread("test_cropped.jpg");
Mat image_copy = img.clone();
int imgheight = img.rows;
int imgwidth = img.cols;

int M = 76;
int N = 104;

int x1 = 0;
int y1 = 0;
for (int y = 0; y<imgheight; y=y+M)
{
    for (int x = 0; x<imgwidth; x=x+N)
    {
        if ((imgheight - y) < M || (imgwidth - x) < N)
        {
            break;
        }
        y1 = y + M;
        x1 = x + N;
        string a = to_string(x);
        string b = to_string(y);

        if (x1 >= imgwidth && y1 >= imgheight)
        {
            x = imgwidth - 1;
            y = imgheight - 1;
            x1 = imgwidth - 1;
            y1 = imgheight - 1;

            // crop the patches of size MxN
            Mat tiles = image_copy(Range(y, imgheight), Range(x, imgwidth));
            //save each patches into file directory
            imwrite("saved_patches/tile" + a + '_' + b + ".jpg", tiles);  
            rectangle(img, Point(x,y), Point(x1,y1), Scalar(0,255,0), 1);    
        }
        else if (y1 >= imgheight)
        {
            y = imgheight - 1;
            y1 = imgheight - 1;

            // crop the patches of size MxN
            Mat tiles = image_copy(Range(y, imgheight), Range(x, x+N));
            //save each patches into file directory
            imwrite("saved_patches/tile" + a + '_' + b + ".jpg", tiles);  
            rectangle(img, Point(x,y), Point(x1,y1), Scalar(0,255,0), 1);    
        }
        else if (x1 >= imgwidth)
        {
            x = imgwidth - 1;   
            x1 = imgwidth - 1;

            // crop the patches of size MxN
            Mat tiles = image_copy(Range(y, y+M), Range(x, imgwidth));
            //save each patches into file directory
            imwrite("saved_patches/tile" + a + '_' + b + ".jpg", tiles);  
            rectangle(img, Point(x,y), Point(x1,y1), Scalar(0,255,0), 1);    
        }
        else
        {
            // crop the patches of size MxN
            Mat tiles = image_copy(Range(y, y+M), Range(x, x+N));
            //save each patches into file directory
            imwrite("saved_patches/tile" + a + '_' + b + ".jpg", tiles);  
            rectangle(img, Point(x,y), Point(x1,y1), Scalar(0,255,0), 1);    
        }
    }
}

imshow("Patched Image", img);
imwrite("patched.jpg",img);
waitKey();
destroyAllWindows();

使用 OpenCV 進行影象旋轉和平移

使用OpenCV進行影象旋轉

Python

import cv2

# Reading the image
image = cv2.imread('image.jpg')

# dividing height and width by 2 to get the center of the image
height, width = image.shape[:2]
# get the center coordinates of the image to create the 2D rotation matrix
center = (width/2, height/2)

# using cv2.getRotationMatrix2D() to get the rotation matrix(得到2D選擇矩陣)
rotate_matrix = cv2.getRotationMatrix2D(center=center, angle=45, scale=1)

# rotate the image using cv2.warpAffine(得到旋轉的影象)
rotated_image = cv2.warpAffine(src=image, M=rotate_matrix, dsize=(width, height))

cv2.imshow('Original image', image)
cv2.imshow('Rotated image', rotated_image)
# wait indefinitely, press any key on keyboard to exit
cv2.waitKey(0)
# save the rotated image to disk
cv2.imwrite('rotated_image.jpg', rotated_image)

C++

#include <iostream>
#include<opencv2/opencv.hpp>
using namespace cv;

int main(int, char**) 
{
    Mat image = imread("image.jpg");
	  imshow("image", image);
	  waitKey(0);
	  double angle = 45;

	  // get the center coordinates of the image to create the 2D rotation matrix
	  Point2f center((image.cols - 1) / 2.0, (image.rows - 1) / 2.0);
	  // using getRotationMatrix2D() to get the rotation matrix
	  Mat rotation_matix = getRotationMatrix2D(center, angle, 1.0);

	  // we will save the resulting image in rotated_image matrix
	  Mat rotated_image;
	  // rotate the image using warpAffine
	  warpAffine(image, rotated_image, rotation_matix, image.size());
	  imshow("Rotated image", rotated_image);
    // wait indefinitely, press any key on keyboard to exit
	  waitKey(0);
	  // save the rotated image to disk
	  imwrite("rotated_im.jpg", rotated_image);

	  return 0;
}

使用OpenCV進行影象的平移

Python

import cv2 
import numpy as np

# read the image 
image = cv2.imread('image.jpg')
# get the width and height of the image
height, width = image.shape[:2]

# get tx and ty values for translation
# you can specify any value of your choice
tx, ty = width / 4, height / 4

# create the translation matrix using tx and ty, it is a NumPy array 
translation_matrix = np.array([
    [1, 0, tx],
    [0, 1, ty]
], dtype=np.float32)

# apply the translation to the image
translated_image = cv2.warpAffine(src=image, M=translation_matrix, dsize=(width, height))

# display the original and the Translated images
cv2.imshow('Translated image', translated_image)
cv2.imshow('Original image', image)
cv2.waitKey(0)
# save the translated image to disk
cv2.imwrite('translated_image.jpg', translated_image)

C++

#include "opencv2/opencv.hpp"
using namespace cv
// read the image 
Mat image = imread("image.jpg");
// get the height and width of the image
int height = image.cols;
int width = image.rows;

// get tx and ty values for translation
float tx = float(width) / 4;
float ty = float(height) / 4;
// create the translation matrix using tx and ty
float warp_values[] = { 1.0, 0.0, tx, 0.0, 1.0, ty };
Mat translation_matrix = Mat(2, 3, CV_32F, warp_values);

// save the resulting image in translated_image matrix
Mat translated_image;
// apply affine transformation to the original image using the translation matrix
warpAffine(image, translated_image, translation_matrix, image.size());

//display the original and the Translated images
imshow("Translated image", translated_image);
imshow("Original image", image);
waitKey(0);
// save the translated image to disk
imwrite("translated_image.jpg", translated_image);