多尺度视网膜增强算法(MSRCR)
2014-12-07 13:53
525 查看
MSRCR(multi-scale retinex with color restoration)
头文件
实现文件
主函数文件
====================================================================================
改进版 视网膜增强算法
====================================================================================
问题:
上面给出的源码,实现后,在颜色比较鲜艳时,或者颜色为黑色时,会产生变色(比如黑色会变为红色,红色会变为黄色)
产生原因:
RGB值比较大的值(接近255) 或比较低的(接近0 ) 经过上述算法处理后,某一通道的值会超过255或低于0,溢出。
改进:
改进版本可参考reference 3(网站包含论文与demo ,源码(Linux版本))
Reference:
1.原理相关1:/article/4875692.html
2.源码部分2:/article/7910142.html
---------------------------------------------------------------------------------------------------------------
3.改进版本:http://www.ipol.im/pub/art/2014/107/
头文件
/* * Copyright (c) 2006, Douglas Gray (dgray@soe.ucsc.edu, dr.de3ug@gmail.com) * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of the <organization> nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY Douglas Gray ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #pragma once #include "cv.h" extern double* CreateKernel(double sigma); extern int* CreateFastKernel(double sigma); extern void FilterGaussian(IplImage* img, double sigma); extern void FastFilter(IplImage *img, double sigma); extern void Retinex (IplImage *img, double sigma, int gain = 128, int offset = 128); extern void MultiScaleRetinex (IplImage *img, int scales, double *weights, double *sigmas, int gain = 128, int offset = 128); extern void MultiScaleRetinexCR (IplImage *img, int scales, double *weights, double *sigmas, int gain = 128, int offset = 128, double restoration_factor = 6, double color_gain = 2);
实现文件
/* * Copyright (c) 2006, Douglas Gray (dgray@soe.ucsc.edu, dr.de3ug@gmail.com) * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of the <organization> nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY Douglas Gray ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "retinex.h" #include<cv.h> #include <opencv2/opencv.hpp> #include<omp.h> #include <math.h> using namespace cv; using namespace std; //#define USE_EXACT_SIGMA #define pc(image, x, y, c) image->imageData[(image->widthStep * y) + (image->nChannels * x) + c] #define INT_PREC 1024.0 #define INT_PREC_BITS 10 inline double int2double(int x) { return (double)x / INT_PREC; } inline int double2int(double x) { return (int)(x * INT_PREC + 0.5); } inline int int2smallint(int x) { return (x >> INT_PREC_BITS); } inline int int2bigint(int x) { return (x << INT_PREC_BITS); } // // CreateKernel // // Summary: // Creates a normalized 1 dimensional gaussian kernel. // // Arguments: // sigma - the standard deviation of the gaussian kernel. // // Returns: // double* - an array of values of length ((6*sigma)/2) * 2 + 1. // // Note: // Caller is responsable for deleting the kernel. // double* CreateKernel(double sigma) { int i, x, filter_size; double* filter; double sum; // Reject unreasonable demands if ( sigma > 200 ) sigma = 200; // get needed filter size (enforce oddness) filter_size = (int)floor(sigma*6) / 2; filter_size = filter_size * 2 + 1; // Allocate kernel space filter = new double[filter_size]; // Calculate exponential sum = 0; for (i = 0; i < filter_size; i++) { x = i - (filter_size / 2); filter[i] = exp( -(x*x) / (2*sigma*sigma) ); sum += filter[i]; } // Normalize for (i = 0, x; i < filter_size; i++) filter[i] /= sum; return filter; } // // CreateFastKernel // // Summary: // Creates a faster gaussian kernal using integers that // approximate floating point (leftshifted by 8 bits) // // Arguments: // sigma - the standard deviation of the gaussian kernel. // // Returns: // int* - an array of values of length ((6*sigma)/2) * 2 + 1. // // Note: // Caller is responsable for deleting the kernel. // int* CreateFastKernel(double sigma) { double* fp_kernel; int* kernel; int i, filter_size; // Reject unreasonable demands if ( sigma > 200 ) sigma = 200; // get needed filter size (enforce oddness) filter_size = (int)floor(sigma*6) / 2; filter_size = filter_size * 2 + 1; // Allocate kernel space kernel = new int[filter_size]; fp_kernel = CreateKernel(sigma); for (i = 0; i < filter_size; i++) kernel[i] = double2int(fp_kernel[i]); delete fp_kernel; return kernel; } // // FilterGaussian // // Summary: // Performs a gaussian convolution for a value of sigma that is equal // in both directions. // // Arguments: // img - the image to be filtered in place. // sigma - the standard deviation of the gaussian kernel to use. // void FilterGaussian(IplImage* img, double sigma) { int i, j, k, source, filter_size; int* kernel; IplImage* temp; int v1, v2, v3; // Reject unreasonable demands if ( sigma > 200 ) sigma = 200; // get needed filter size (enforce oddness) filter_size = (int)floor(sigma*6) / 2; filter_size = filter_size * 2 + 1; kernel = CreateFastKernel(sigma); temp = cvCreateImage(cvSize(img->width, img->height), img->depth, img->nChannels); // filter x axis for (j = 0; j < temp->height; j++) for (i = 0; i < temp->width; i++) { // inner loop has been unrolled v1 = v2 = v3 = 0; for (k = 0; k < filter_size; k++) { source = i + filter_size / 2 - k; if (source < 0) source *= -1; if (source > img->width - 1) source = 2*(img->width - 1) - source; v1 += kernel[k] * (unsigned char)pc(img, source, j, 0); if (img->nChannels == 1) continue; v2 += kernel[k] * (unsigned char)pc(img, source, j, 1); v3 += kernel[k] * (unsigned char)pc(img, source, j, 2); } // set value and move on pc(temp, i, j, 0) = (char)int2smallint(v1); if (img->nChannels == 1) continue; pc(temp, i, j, 1) = (char)int2smallint(v2); pc(temp, i, j, 2) = (char)int2smallint(v3); } // filter y axis for (j = 0; j < img->height; j++) for (i = 0; i < img->width; i++) { v1 = v2 = v3 = 0; for (k = 0; k < filter_size; k++) { source = j + filter_size / 2 - k; if (source < 0) source *= -1; if (source > temp->height - 1) source = 2*(temp->height - 1) - source; v1 += kernel[k] * (unsigned char)pc(temp, i, source, 0); if (img->nChannels == 1) continue; v2 += kernel[k] * (unsigned char)pc(temp, i, source, 1); v3 += kernel[k] * (unsigned char)pc(temp, i, source, 2); } // set value and move on pc(img, i, j, 0) = (char)int2smallint(v1); if (img->nChannels == 1) continue; pc(img, i, j, 1) = (char)int2smallint(v2); pc(img, i, j, 2) = (char)int2smallint(v3); } cvReleaseImage( &temp ); delete kernel; } // // FastFilter // // Summary: // Performs gaussian convolution of any size sigma very fast by using // both image pyramids and seperable filters. Recursion is used. // // Arguments: // img - an IplImage to be filtered in place. // void FastFilter(IplImage *img, double sigma) { int filter_size; // Reject unreasonable demands if ( sigma > 200 ) sigma = 200; // get needed filter size (enforce oddness) filter_size = (int)floor(sigma*6) / 2; filter_size = filter_size * 2 + 1; // If 3 sigma is less than a pixel, why bother (ie sigma < 2/3) if(filter_size < 3) return; // Filter, or downsample and recurse if (filter_size < 10) { #ifdef USE_EXACT_SIGMA FilterGaussian(img, sigma) #else cvSmooth( img, img, CV_GAUSSIAN, filter_size, filter_size ); #endif } else { if (img->width < 2 || img->height < 2) return; IplImage* sub_img = cvCreateImage(cvSize(img->width / 2, img->height / 2), img->depth, img->nChannels); cvPyrDown( img, sub_img ); FastFilter( sub_img, sigma / 2.0 ); cvResize( sub_img, img, CV_INTER_LINEAR ); cvReleaseImage( &sub_img ); } } // // Retinex // // Summary: // Basic retinex restoration. The image and a filtered image are converted // to the log domain and subtracted. // // Arguments: // img - an IplImage to be enhanced in place. // sigma - the standard deviation of the gaussian kernal used to filter. // gain - the factor by which to scale the image back into visable range. // offset - an offset similar to the gain. // void Retinex(IplImage *img, double sigma, int gain, int offset) { IplImage *A, *fA, *fB, *fC; // Initialize temp images fA = cvCreateImage(cvSize(img->width, img->height), IPL_DEPTH_32F, img->nChannels); fB = cvCreateImage(cvSize(img->width, img->height), IPL_DEPTH_32F, img->nChannels); fC = cvCreateImage(cvSize(img->width, img->height), IPL_DEPTH_32F, img->nChannels); // Compute log image cvConvert( img, fA ); cvLog( fA, fB ); // Compute log of blured image A = cvCloneImage( img ); FastFilter( A, sigma ); cvConvert( A, fA ); cvLog( fA, fC ); // Compute difference cvSub( fB, fC, fA ); // Restore cvConvertScale( fA, img, gain, offset); // Release temp images cvReleaseImage( &A ); cvReleaseImage( &fA ); cvReleaseImage( &fB ); cvReleaseImage( &fC ); } // // MultiScaleRetinex // // Summary: // Multiscale retinex restoration. The image and a set of filtered images are // converted to the log domain and subtracted from the original with some set // of weights. Typicaly called with three equaly weighted scales of fine, // medium and wide standard deviations. // // Arguments: // img - an IplImage to be enhanced in place. // sigma - the standard deviation of the gaussian kernal used to filter. // gain - the factor by which to scale the image back into visable range. // offset - an offset similar to the gain. // void MultiScaleRetinex(IplImage *img, int scales, double *weights, double *sigmas, int gain, int offset) { int i; double weight; IplImage *A, *fA, *fB, *fC; // Initialize temp images fA = cvCreateImage(cvSize(img->width, img->height), IPL_DEPTH_32F, img->nChannels); fB = cvCreateImage(cvSize(img->width, img->height), IPL_DEPTH_32F, img->nChannels); fC = cvCreateImage(cvSize(img->width, img->height), IPL_DEPTH_32F, img->nChannels); // Compute log image cvConvert( img, fA ); cvLog( fA, fB ); // Normalize according to given weights for (i = 0, weight = 0; i < scales; i++) weight += weights[i]; if (weight != 1.0) cvScale( fB, fB, weight ); // Filter at each scale for (i = 0; i < scales; i++) { A = cvCloneImage( img ); FastFilter( A, sigmas[i] ); cvConvert( A, fA ); cvLog( fA, fC ); cvReleaseImage( &A ); // Compute weighted difference cvScale( fC, fC, weights[i] ); cvSub( fB, fC, fB ); } // Restore cvConvertScale( fB, img, gain, offset); // Release temp images cvReleaseImage( &fA ); cvReleaseImage( &fB ); cvReleaseImage( &fC ); } // // MultiScaleRetinexCR // // Summary: // Multiscale retinex restoration with color restoration. The image and a set of // filtered images are converted to the log domain and subtracted from the // original with some set of weights. Typicaly called with three equaly weighted // scales of fine, medium and wide standard deviations. A color restoration weight // is then applied to each color channel. // // Arguments: // img - an IplImage to be enhanced in place. // sigma - the standard deviation of the gaussian kernal used to filter. // gain - the factor by which to scale the image back into visable range. // offset - an offset similar to the gain. // restoration_factor - controls the non-linearaty of the color restoration. // color_gain - controls the color restoration gain. // //extern void MultiScaleRetinexCR //(IplImage *img, int scales, double *weights, double *sigmas, int gain = 128, int offset = 128, // double restoration_factor = 6, double color_gain = 2); void MultiScaleRetinexCR(IplImage *img, int scales, double *weights, double *sigmas, int gain, int offset, double restoration_factor, double color_gain) { int i; double weight; IplImage *A, *B, *C, *fA, *fB, *fC, *fsA, *fsB, *fsC, *fsD, *fsE, *fsF; // Initialize temp images fA = cvCreateImage(cvSize(img->width, img->height), IPL_DEPTH_32F, img->nChannels); fB = cvCreateImage(cvSize(img->width, img->height), IPL_DEPTH_32F, img->nChannels); fC = cvCreateImage(cvSize(img->width, img->height), IPL_DEPTH_32F, img->nChannels); fsA = cvCreateImage(cvSize(img->width, img->height), IPL_DEPTH_32F, 1); fsB = cvCreateImage(cvSize(img->width, img->height), IPL_DEPTH_32F, 1); fsC = cvCreateImage(cvSize(img->width, img->height), IPL_DEPTH_32F, 1); fsD = cvCreateImage(cvSize(img->width, img->height), IPL_DEPTH_32F, 1); fsE = cvCreateImage(cvSize(img->width, img->height), IPL_DEPTH_32F, 1); fsF = cvCreateImage(cvSize(img->width, img->height), IPL_DEPTH_32F, 1); // Compute log image cvConvert( img, fB ); cvLog( fB, fA ); ////=================get image value=================== // const int height=26; //const int width=30; //float imageValue[height][width][3]; //for(int i=0;i<img->height;i++) //{ // for(int j=0;j<img->width;j++) // { // imageValue[i][j][0]=cvGet2D(fA,i,j).val[0]; // imageValue[i][j][1]=cvGet2D(fA,i,j).val[1]; // imageValue[i][j][2]=cvGet2D(fA,i,j).val[2]; // } //} ////===========================end====================== //////=============================show image================ //IplImage * test = cvCreateImage(cvSize(img->width, img->height), IPL_DEPTH_8U, img->nChannels); //cvConvert(fB,test); //cvNamedWindow("test",CV_WINDOW_AUTOSIZE); //cvShowImage("test",test); //cvWaitKey(0); ////==========================end============================ // Normalize according to given weights for (i = 0, weight = 0; i < scales; i++) weight += weights[i]; if (weight != 1.0) cvScale( fA, fA, weight ); // Filter at each scale // for (i = 0; i < scales; i++) { A = cvCloneImage( img ); FastFilter( A, sigmas[i] ); cvConvert( A, fB ); cvLog( fB, fC ); cvReleaseImage( &A ); // Compute weighted difference cvScale( fC, fC, weights[i] ); cvSub( fA, fC, fA ); } // Color restoration if (img->nChannels > 1) { A = cvCreateImage(cvSize(img->width, img->height), img->depth, 1); B = cvCreateImage(cvSize(img->width, img->height), img->depth, 1); C = cvCreateImage(cvSize(img->width, img->height), img->depth, 1); // Divide image into channels, convert and store sum cvCvtPixToPlane( img, A, B, C, NULL ); cvConvert( A, fsA ); cvConvert( B, fsB ); cvConvert( C, fsC ); cvReleaseImage( &A ); cvReleaseImage( &B ); cvReleaseImage( &C ); // Sum components cvAdd( fsA, fsB, fsD ); cvAdd( fsD, fsC, fsD ); // Normalize weights cvDiv( fsA, fsD, fsA, restoration_factor); cvDiv( fsB, fsD, fsB, restoration_factor); cvDiv( fsC, fsD, fsC, restoration_factor); cvConvertScale( fsA, fsA, 1, 1 ); cvConvertScale( fsB, fsB, 1, 1 ); cvConvertScale( fsC, fsC, 1, 1 ); // Log weights cvLog( fsA, fsA ); cvLog( fsB, fsB ); cvLog( fsC, fsC ); // Divide retinex image, weight accordingly and recombine cvCvtPixToPlane( fA, fsD, fsE, fsF, NULL ); cvMul( fsD, fsA, fsD, color_gain); cvMul( fsE, fsB, fsE, color_gain ); cvMul( fsF, fsC, fsF, color_gain ); cvCvtPlaneToPix( fsD, fsE, fsF, NULL, fA ); } // Restore cvConvertScale( fA, img, gain, offset); // Release temp images cvReleaseImage( &fA ); cvReleaseImage( &fB ); cvReleaseImage( &fC ); cvReleaseImage( &fsA ); cvReleaseImage( &fsB ); cvReleaseImage( &fsC ); cvReleaseImage( &fsD ); cvReleaseImage( &fsE ); cvReleaseImage( &fsF ); }
主函数文件
//#include "stdafx.h" #include<tchar.h> #include <opencv2/opencv.hpp> #include<iostream> #include<sstream> #include<string> #include<cv.h> #include<omp.h> #include<concrt.h> #include"retinex.h" using namespace std; using namespace cv; //============================================using for handle single image================================================== int _tmain(int argc, _TCHAR* argv[]) { //get image const char* imagename = "girl.jpg"; const char* imagesavename="girl_retinex.jpg"; /*const char* imagename[6] = {"example12.jpg","girl01.jpg","people01.jpg","road01.jpg","tree01.jpg","clock.bmp"}; const char* imagesavename[6] = {"example12_retinex.jpg","girl01_retinex.jpg","people01_retinex.jpg","road01_retinex.jpg", "tree01_retinex.jpg","clock_retinex.bmp"};*/ //set retinex parameters int scales=3; double weight[3]={1.0/3.0,1.0/3.0,1.0/3.0}; double sigmas[3]={1,50,100}; //- the standard deviation of the gaussian kernal used to filter. int gain=50; //- the factor by which to scale the image back into visable range. int offset=150; //- an offset similar to the gain. double restoration_factor=100; // - controls the non-linearaty of the color restoration. double color_gain=1; // - controls the color restoration gain. char filePath[200]="image\\"; char* imagePath=filePath; //get savefilename char num[5]; char* sigmas_char[3]; stringstream ss; for(int j=0;j<3;j++) { sigmas_char[j]=num; ss<<sigmas[j]; ss>>sigmas_char[j]; imagePath=strcat(imagePath,"sigma="); imagePath=strcat(imagePath,sigmas_char[j]); ss.clear(); ss.str(""); } //gain ss.clear(); ss.str(""); char* gain_c=num; ss<<gain; ss>>gain_c; imagePath=strcat(imagePath,"_gain="); imagePath=strcat(imagePath,gain_c); //offset ss.clear(); ss.str(""); char* offset_char=num; ss<<offset; ss>>offset_char; imagePath=strcat(imagePath,"_offset="); imagePath=strcat(imagePath,offset_char); //restoration_factor ss.clear(); ss.str(""); char* restoration_factor_char=num; ss<<restoration_factor; ss>>restoration_factor_char; imagePath=strcat(imagePath,"_factor="); imagePath=strcat(imagePath,restoration_factor_char); //color_gain ss.clear(); ss.str(""); char* color_gain_char=num; ss<<color_gain; ss>>color_gain_char; imagePath=strcat(imagePath,"_color_gain="); imagePath=strcat(imagePath,color_gain_char); ss.clear(); ss.str(""); const char* imageSavePath=strcat(imagePath,imagesavename); IplImage* img=cvLoadImage(imagename,-1);//read the original channels number from image MultiScaleRetinexCR(img,scales,weight,sigmas, gain, offset,restoration_factor,color_gain); cvSaveImage(imageSavePath,img); cvReleaseImage(&img); return 0; } ////============================================end========================================================= //==========================================using for handle video============================== //int _tmain(int argc, _TCHAR* argv[]) //{ // //get core num // int coreNum=omp_get_num_procs(); // // IplImage* pFrame=NULL; // CvCapture* pCapture=NULL; // // cvNamedWindow("orginalVideo",1); // cvNamedWindow("retinexVideo",1); // // cvMoveWindow("video",30,0); // cvMoveWindow("retinexVideo",360,0); // // const char* videoName="sister.avi"; // if(!(pCapture=cvCaptureFromFile(videoName))) // { // fprintf(stderr, "Can not open video file %s\n", videoName); // return -1; // } // // /*CvVideoWriter *writer=0; // int isColor=1; // int fps=cvGetCaptureProperty(pCapture,CV_CAP_PROP_FPS); // int frameW=cvGetCaptureProperty(pCapture,CV_CAP_PROP_FRAME_HEIGHT); // int frameH=cvGetCaptureProperty(pCapture,CV_CAP_PROP_FRAME_WIDTH); // int numFrames = (int) cvGetCaptureProperty(pCapture, CV_CAP_PROP_FRAME_COUNT); // writer=cvCreateVideoWriter("sister2retinex.avi",CV_FOURCC('M','J','P','G'), // fps,cvSize(frameH,frameW),isColor);*/ // // //set paramaters // int scales=3; // double *weights,weight[3]={1.0/3.0,1.0/3.0,1.0/3.0}; // weights=&weight[0]; // double *sigmas, simg[3]={10,50,100}; // sigmas=&simg[0]; // // int count=0; // // while((pFrame=cvQueryFrame(pCapture))!=NULL) // { // count++; // cvShowImage("orginalVideo",pFrame); // cvWaitKey(1); // MultiScaleRetinexCR(pFrame,scales,weights,sigmas, 128, 128,6,2); // /*cvWriteFrame(writer,pFrame);*/ // cvShowImage("retinexVideo",pFrame); // //cout<<count<<"/"<<numFrames<<endl; // } // cvDestroyWindow("orginalVideo"); // cvDestroyWindow("retinexVideo"); // // cvReleaseImage(&pFrame); // cvReleaseCapture(&pCapture); // //cvReleaseVideoWriter(&writer); // return 0; //} //=====================================end========================================================
====================================================================================
改进版 视网膜增强算法
====================================================================================
问题:
上面给出的源码,实现后,在颜色比较鲜艳时,或者颜色为黑色时,会产生变色(比如黑色会变为红色,红色会变为黄色)
产生原因:
RGB值比较大的值(接近255) 或比较低的(接近0 ) 经过上述算法处理后,某一通道的值会超过255或低于0,溢出。
改进:
改进版本可参考reference 3(网站包含论文与demo ,源码(Linux版本))
Reference:
1.原理相关1:/article/4875692.html
2.源码部分2:/article/7910142.html
---------------------------------------------------------------------------------------------------------------
3.改进版本:http://www.ipol.im/pub/art/2014/107/
相关文章推荐
- 带色彩恢复的多尺度视网膜增强算法(MSRCR)的原理、实现及应用。
- 带色彩恢复的多尺度视网膜增强算法(MSRCR)的原理、实现及应用。
- 带色彩恢复的多尺度视网膜增强算法(MSRCR)的原理、实现及应用。
- 带色彩恢复的多尺度视网膜增强算法(MSRCR)的原理、实现及应用。
- msrcr(Multi-Scale Retinex with Color Restoration) 带色彩恢复的多尺度视网膜增强算法 整理
- 带色彩恢复的多尺度视网膜增强算法(MSRCR)的原理、实现及应用
- 带色彩恢复的多尺度视网膜增强算法(MSRCR)的原理、实现及应用
- 带色彩恢复的多尺度视网膜增强算法(MSRCR)的原理、实现及应用。
- 带色彩恢复的多尺度视网膜增强算法(MSRCR)的原理、实现及应用。
- 带色彩恢复信息的多尺度视网膜增强算法(MSRCR)
- 带色彩恢复的视网膜增强算法实现 (MATLAB版本)
- 基于多尺度对比度x射线图像增强算法2
- MSRCR(Multi-Scale Retinex with Color Restore)多尺度Retinex图像增强
- 图像多尺度对比增强算法
- 图像增强算法四种,图示与源码,包括retinex(ssr、msr、msrcr)和一种混合算法
- 图像增强算法四种,图示与源码,包括retinex(ssr、msr、msrcr)和一种混合算法
- 图像增强算法四种,图示与源码,包括retinex(ssr、msr、msrcr)和一种混合算法
- MUSICA(多尺度图像对比度增强)算法的简要原理及VC实现-1[r]
- 图像增强算法四种,图示与源码,包括retinex(ssr、msr、msrcr)和一种混合算法
- MUSICA(多尺度图像对比度增强)算法的简要原理及VC实现