PDA

View Full Version : الگوریتم پردازش تصویر برای پیاده سازی فیلتر stamp در فتوشاپ



mst_ab
چهارشنبه 22 آذر 1391, 16:26 عصر
سلام بر متخصصین گرامی، من فقط یه الگوریتم رو میخوام، کسی بتونه بهم بگه، خودم پیاده می کنم.
برای اینکه دقیقاً بدونید من چی میگم، یه عکس تو فتوشاپ باز کنید و بعد از منوی فیلترها برید اینجا:
sketch-> stamp
این فیلتر استامپ (مهر) درست می کنه. من هر چی تلاش کردم، نتونستم الگوریتمی که پشت این فیلتر هست رو استخراج کنم. من خودم پی اچ پی کارم، می خوام با GD پیاده کنم، تنها مشکلم الآن همین الگوریتم این فیلتر هست. فایل توضیحات رو هم ضمیمه کردم.

با تشکر

مصطفی ساتکی
جمعه 24 آذر 1391, 14:15 عصر
این stamp که شما مطرح کردید در حالت ساده می تونه یک threshold معمولی باشه و در حالت پیشرفته تر که در شرایط مختلف تصویر stamp بهتری بهمون بده میشه از threshold های آماری و دقیق تر همچون otsu threshold (http://barnamenevis.org/showthread.php?299704-Otsu-thresholding-%D8%AF%D8%B1-%D9%BE%D8%B1%D8%AF%D8%A7%D8%B2%D8%B4-%D8%AA%D8%B5%D9%88%D9%8A%D8%B1&highlight=otsu) یا adaptive threshold استفاده نماید

mst_ab
جمعه 24 آذر 1391, 14:19 عصر
ممنون از توضیحات، بنده این سوال رو در stackoverflow مطرح کردم، و این الگوریتم چند مرحله ای زیر رو پیشنهاد دادن:


Convert the image to grayscale.
Make a copy and invert the intensities.
Blur the copy.
Combine the two images using a Color Dodge formula (http://en.wikipedia.org/wiki/Blend_modes#Dodge_and_burn).

من در مورد آخری هیچی نمیدونم، ممکنه یه توضیح مختصر بدید چطوری باید دو تا عکس رو با یه فرمول color dodge ترکیب کنم؟ البته (عکس ورودی سیاه سفید هست، گفتم بگم شاید لازم باشه)

مصطفی ساتکی
جمعه 24 آذر 1391, 20:09 عصر
کل مراحلش میشه یه همچین چیزی.
البته این کد با c++ و کتابخانه OpenCV هستش هر جاشو خواستید بفرماید توضیح بدم.

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

int main( int argc, char** argv )
{
int col_1, row_1;
uchar b_1, g_1, r_1, b_2, g_2, r_2, b_d, g_d, r_d;

IplImage* img = cvLoadImage("test.png");
IplImage* img1 = cvCreateImage( cvSize( img->width,img->height ), img->depth, img->nChannels);
IplImage* img2 = cvCreateImage( cvSize( img->width,img->height ), img->depth, img->nChannels);
IplImage* dst = cvCreateImage( cvSize( img->width,img->height ), img->depth, img->nChannels);
IplImage* gray= cvCreateImage(cvGetSize(img), img->depth, 1);

cvNamedWindow("Input", CV_WINDOW_AUTOSIZE );
cvNamedWindow("Output", CV_WINDOW_AUTOSIZE );

cvShowImage("Input", img );
cvNot(img, img1);
// cvSmooth(img1, img2, CV_BLUR, 25,25,0,0);
cvSmooth(img, img2, CV_GAUSSIAN, 7, 7, 0, 0); // last fix :)

for( row_1 = 0; row_1 < img1->height; row_1++ )
{
for ( col_1 = 0; col_1 < img1->width; col_1++ )
{
b_1 = CV_IMAGE_ELEM( img1, uchar, row_1, col_1 * 3 );
g_1 = CV_IMAGE_ELEM( img1, uchar, row_1, col_1 * 3 + 1 );
r_1 = CV_IMAGE_ELEM( img1, uchar, row_1, col_1 * 3 + 2 );

b_2 = CV_IMAGE_ELEM( img2, uchar, row_1, col_1 * 3 );
g_2 = CV_IMAGE_ELEM( img2, uchar, row_1, col_1 * 3 + 1 );
r_2 = CV_IMAGE_ELEM( img2, uchar, row_1, col_1 * 3 + 2 );


b_d = std::min(255, b_1 + b_2);
g_d = std::min(255, g_1 + g_2);
r_d = std::min(255, r_1 + r_2);

dst->imageData[img1->widthStep * row_1 + col_1* 3] = b_d;
dst->imageData[img1->widthStep * row_1 + col_1 * 3 + 1] = g_d;
dst->imageData[img1->widthStep * row_1 + col_1 * 3 + 2] = r_d;
}
}
cvCvtColor(dst, gray, CV_BGR2GRAY);
cvShowImage("Output", gray );

cvWaitKey(0);
cvReleaseImage( &img );
cvReleaseImage( &img1 ); // Yes, you must release all the allocated memory.
cvReleaseImage( &img2 );
cvReleaseImage( &dst );
cvReleaseImage( &gray);
cvDestroyWindow("Input");
cvDestroyWindow("Output");
}