Article: Trộn ảnh 1441

giải thuật căn bản về xử lí ảnh
ngocdaothanh.myopenid.com 149
Updated about 1 year ago

Trộn ảnh là hiệu ứng rất bắt mắt, nhưng lại rất dễ thực hiện. Ảnh dưới là Baboon và Lenna trộn với nhau, trông rất ấn tượng, có thể mang đi quảng cáo phim King Kong phải không ạ!

Nếu biết cách trộn 2 pixel, ta sẽ biết cách trộn 2 ảnh. Đối với ảnh grayscale, công thức để trộn 2 pixel như sau:

i = r*i1 + (1 - r)*i2

Trong đó i1 và i2 là độ xám (intensity) của 2 pixel, r là số từ 0 đến 1. Mở rộng công thức này, ta có thể trộn ảnh màu, thậm chí 3, 4 ảnh với nhau.

Dưới đây là chương trình mẫu, sử dụng thư viện OpenCV.

#include <stdio.h>
#include <cv.h>
#include <highgui.h>

#define FILE_NAME1 "baboon.jpg"
#define FILE_NAME2 "lenna.jpg"
#define WINDOW_NAME "Output"

IplImage *img1, *img2, *blended;

void trackbarHandler(int pos);

int main() {
img1 = cvLoadImage(FILE_NAME1);
if (!img1) {
printf("Cannot open %s\n", FILE_NAME1);
return -1;
}

img2 = cvLoadImage(FILE_NAME2);
if (!img2) {
cvReleaseImage(&img1);
printf("Cannot open %s\n", FILE_NAME2);
return -1;
}

// The two images should have the same properties
if (img1->width != img2->width ||
img1->height != img2->height ||
img1->nChannels != img2->nChannels) {
cvReleaseImage(&img1);
cvReleaseImage(&img2);
printf("The two images should have the same properties\n");
return -1;
}

blended = cvCreateImage(cvSize(img1->width, img1->height),
img1->depth, img1->nChannels);

cvNamedWindow(WINDOW_NAME);
int blendRatio = 50; // 0 - 100 [%]
cvCreateTrackbar("Ratio", WINDOW_NAME, &blendRatio, 100, trackbarHandler);

trackbarHandler(blendRatio);

cvWaitKey();
cvReleaseImage(&img1);
cvReleaseImage(&img2);
cvReleaseImage(&blended);
}

void trackbarHandler(int pos) {
int width = img1->width;
int height = img1->height;
int step = img1->widthStep/(img1->depth/8);
int channels = img1->nChannels;

uchar* data1 = (uchar *)img1->imageData;
uchar* data2 = (uchar *)img2->imageData;
uchar* dataB = (uchar *)blended->imageData;

for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
for (int k = 0; k < channels; k++) {
int e = i*step + j*channels + k;
double r = pos/100.0; // Ratio, 0.0 - 1.0
dataB[e] = r*data1[e] + (1 - r)*data2[e];
}
}
}


cvShowImage(WINDOW_NAME, blended);
}

Có thể sửa đổi một chút để thực hiện hiệu ứng hiện ảnh ra dần dần (fade in, thường từ màu đen) hoặc làm ảnh biến mất dần dần (fade out, thường thành màu đen).

1 2 3 

Editors
ngocdaothanh.myopenid.com 149
phananhvu.myopenid.com 125

Comments

ngocdaothanh.myopenid.com 149
over 2 years ago

Nếu koko kiro không biết lập trình thì chỉ cần hiểu ý tưởng để trộn 2 ảnh với nhau xuất phát từ trộn 2 điểm màu với nhau: lấy mỗi màu 1 ít rồi cộng với nhau. Đây là cách đơn giản nhất, có nhiều cách phức tạp hơn không dùng phép cộng, mà dùng nhân hoặc trừ chẳng hạn.

Nếu biết lập trình C trên Windows, thì cài thư viện OpenCV rồi biên dịch thử chạy thử đoạn mã ví dụ trên sẽ thấy kết quả.

alide.myopenid.com 32
about 1 year ago

Công thức i = r*i1 + (1 - r)*i2 là công thức đơn giản nhất. Có nhiều công thức khác, nên tham khảo hàm glBlendFunc của OpenGL.

You must login to be able to comment

Uploaded files

No file uploaded yet

You must login to be able to upload

Nhà tài trợ:

Mọi người đều tự do viết bài, sửa bài của người khác, và bình luận ở trang web này. Bạn muốn chủ động tạo bài mới để chia sẻ kinh nghiệm với mọi người? Xin click link ở dưới.

Create new content