Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //
- // OpenCVWrapper.m
- // Vyu360
- //
- // Created by 2Mac on 22.03.2019.
- // Copyright © 2019 2Mac. All rights reserved.
- //
- #import "OpenCVWrapper.h"
- #import "OpenCVUIImage.h"
- #import <opencv2/opencv.hpp>
- #import <opencv2/highgui/highgui_c.h>
- #import <math.h>
- #import <unistd.h>
- #import <getopt.h>
- #import <iostream>
- @interface OpenCVWrapper ()
- +(void) buildGaussianPyramid;
- +(void) buildLaplacianPyramid:(cv::Mat&) img withLapPyr: (std::vector<cv::Mat_<cv::Vec3f>>&)lapPyr withSmallestLevel: (cv::Mat&)smallestLevel;
- @end
- @implementation OpenCVWrapper
- static cv::Mat map1;
- static cv::Mat map2;
- float xscale;
- float yscale;
- float xshift;
- float yshift;
- cv::Mat_<cv::Vec3f> left;
- cv::Mat_<cv::Vec3f> right;
- cv::Mat_<float> blendMask;
- cv::Mat leftSmallestLevel, rightSmallestLevel, resultSmallestLevel;
- std::vector<cv::Mat_<cv::Vec3f>> leftLapPyr;
- std::vector<cv::Mat_<cv::Vec3f>> rightLapPyr;
- std::vector<cv::Mat_<cv::Vec3f>> resultLapPyr;
- std::vector<cv::Mat_<cv::Vec3f>> maskGaussianPyramid; //masks are 3-channels for easier multiplication with RGB
- int levels;
- +(void) buildGaussianPyramid
- {
- CV_Assert(leftLapPyr.size()>0);
- maskGaussianPyramid.clear();
- cv::Mat currentImg;
- cvtColor(blendMask, currentImg, CV_GRAY2BGR);
- maskGaussianPyramid.push_back(currentImg); //highest level
- currentImg = blendMask;
- for (int l=1; l<levels+1; l++) {
- cv::Mat _down;
- if (leftLapPyr.size() > l) {
- cv::pyrDown(currentImg, _down, leftLapPyr[l].size());
- } else {
- cv::pyrDown(currentImg, _down, leftSmallestLevel.size()); //smallest level
- }
- cv::Mat down;
- cv::cvtColor(_down, down, CV_GRAY2BGR);
- maskGaussianPyramid.push_back(down);
- currentImg = _down;
- }
- }
- +(void) buildLaplacianPyramid:(cv::Mat&) img withLapPyr: (std::vector<cv::Mat_<cv::Vec3f>>&)lapPyr withSmallestLevel: (cv::Mat&)smallestLevel
- {
- lapPyr.clear();
- cv::Mat currentImg = img;
- for (int l=0; l<levels; l++) {
- cv::Mat down,up;
- pyrDown(currentImg, down);
- pyrUp(down, up, currentImg.size());
- cv::Mat lap = currentImg - up;
- lapPyr.push_back(lap);
- currentImg = down;
- }
- currentImg.copyTo(smallestLevel);
- }
- +(cv::Mat_<cv::Vec3f>) reconstructImgFromLapPyramid {
- cv::Mat currentImg = resultSmallestLevel;
- for (int l=levels-1; l>=0; l--) {
- cv::Mat up;
- cv::pyrUp(currentImg, up, resultLapPyr[l].size());
- currentImg = up + resultLapPyr[l];
- }
- return currentImg;
- }
- +(void) blendLapPyrs{
- resultSmallestLevel = leftSmallestLevel.mul(maskGaussianPyramid.back()) +
- rightSmallestLevel.mul(cv::Scalar(1.0,1.0,1.0) - maskGaussianPyramid.back());
- for (int l=0; l<levels; l++) {
- cv::Mat A = leftLapPyr[l].mul(maskGaussianPyramid[l]);
- cv::Mat antiMask = cv::Scalar(1.0,1.0,1.0) - maskGaussianPyramid[l];
- cv::Mat B = rightLapPyr[l].mul(antiMask);
- cv::Mat_<cv::Vec3f> blendedLevel = A + B;
- resultLapPyr.push_back(blendedLevel);
- }
- }
- +(cv::Mat_<cv::Vec3f>) buildPyramid{
- [OpenCVWrapper buildLaplacianPyramid:left withLapPyr:leftLapPyr withSmallestLevel:leftSmallestLevel];
- [OpenCVWrapper buildLaplacianPyramid:right withLapPyr:rightLapPyr withSmallestLevel:rightSmallestLevel];
- [OpenCVWrapper buildGaussianPyramid];
- [OpenCVWrapper blendLapPyrs];
- return [OpenCVWrapper reconstructImgFromLapPyramid];
- }
- +(NSString *) openCVVersionString
- {
- return [NSString stringWithFormat:@"OpenCV Version %s", CV_VERSION];
- }
- +(int) detectLensRadius:(UIImage*)inputPhoto
- {
- cv::Mat input = inputPhoto.CVMat;
- cv::Mat grayscale;
- cv::cvtColor(input, grayscale, cv::COLOR_BGRA2GRAY);
- std::vector<cv::Vec3f> circles;
- cv::HoughCircles(grayscale, circles, cv::HOUGH_GRADIENT, 1, 400);
- cv::Vec3i circle = circles[0];
- int result = circle[2];
- return result;
- }
- +(UIImage *) cropImage:(UIImage*)inputPhoto
- {
- cv::Mat input = inputPhoto.CVMat;
- cv::Mat croppedMat;
- cv::Mat resultMat;
- input(cv::Rect(0, 9, 2048, 1014)).copyTo(croppedMat);
- cv::resize(croppedMat, resultMat, cv::Size(2048, 1024));
- UIImage * result = [UIImage imageWithCVMat: resultMat];
- return result;
- }
- +(UIImage *) resizeToNormalResolution:(UIImage*)inputPhoto :(int)width :(int)height
- {
- cv::Mat input = inputPhoto.CVMat;
- cv::Mat resultMat;
- cv::resize(input, resultMat, cv::Size(width, height));
- UIImage * result = [UIImage imageWithCVMat: resultMat];
- return result;
- }
- +(UIImage *) reflectBorders:(UIImage*)inputPhoto
- {
- cv::Mat input = inputPhoto.CVMat;
- cv::Mat reflected;
- cv::copyMakeBorder(input, reflected, 20, 20, 20, 20, cv::BORDER_REFLECT);
- UIImage * result = [UIImage imageWithCVMat: reflected];
- return result;
- }
- + (UIImage *)inpaintImage:(UIImage*)inputImage withMask:(UIImage*)mask
- {
- cv::Mat inputBGRA =inputImage.CVMat;
- cv::Mat input;
- cv::cvtColor(inputBGRA,input,CV_BGRA2BGR);
- input.convertTo(input,CV_8UC3);
- int sizeSide = 512;
- int sizeCenter = 1024;
- int sizeCrop = 3;
- int sizeHeight = 1024;
- int sizeWeight = 2048;
- int newSizeSide = sizeSide-sizeCrop;
- int newSizeCenter = sizeCenter-sizeCrop*2;
- int newSizeWeight= newSizeCenter+sizeSide*2;
- cv::Ptr<cv::detail::ExposureCompensator> compensator = cv::detail::ExposureCompensator::createDefault(cv::detail::ExposureCompensator::GAIN);
- std::vector<cv::Point> corners;
- std::vector<cv::UMat> images;
- std::vector<cv::UMat> masks;
- corners.push_back(cv::Point(0,0));
- corners.push_back(cv::Point(512,0));
- corners.push_back(cv::Point(1536,0));
- cv::UMat sideULeft(sizeHeight,sizeSide,CV_8UC3,cv::Scalar(0,0,0)),sideURight(sizeHeight,sizeSide,CV_8UC3,cv::Scalar(0,0,0)),UCenter(sizeHeight,sizeCenter,CV_8UC3,cv::Scalar(0,0,0));
- cv::UMat maskCenter(sizeHeight,sizeCenter,CV_8U,cv::Scalar(255)),maskSide(sizeHeight,sizeSide,CV_8U,cv::Scalar(255));
- input(cv::Rect(0,0,sizeSide,sizeHeight)).copyTo(sideULeft);
- input(cv::Rect(sizeSide+sizeCenter,0,sizeSide,sizeHeight)).copyTo(sideURight);
- input(cv::Rect(sizeSide,0,sizeCenter,sizeHeight)).copyTo(UCenter);
- images.push_back(sideULeft);
- images.push_back(UCenter);
- images.push_back(sideURight);
- masks.push_back(maskSide);
- masks.push_back(maskCenter);
- masks.push_back(maskSide);
- compensator->feed(corners,images, masks);
- for(auto i =0;i<3;i++)
- {
- compensator->apply(i, corners[i], images[i], masks[i]);
- }
- sideULeft.copyTo(input(cv::Rect(0,0,sizeSide,sizeHeight)));
- sideURight.copyTo(input(cv::Rect(sizeSide+sizeCenter,0,sizeSide,sizeHeight)));
- UCenter.copyTo(input(cv::Rect(sizeSide,0,sizeCenter,sizeHeight)));
- input.convertTo(input,CV_32FC3);
- cv::Mat result(sizeHeight,sizeWeight - sizeCrop*4,CV_32FC3,cv::Scalar(0,0,0));
- input(cv::Rect(0,0,sizeSide-sizeCrop,sizeHeight)).copyTo(result(cv::Rect(0,0,sizeSide-sizeCrop,sizeHeight)));
- input(cv::Rect(sizeSide+sizeCrop,0,sizeCenter-sizeCrop*2,sizeHeight)).copyTo(result(cv::Rect(sizeSide-sizeCrop,0,sizeCenter-sizeCrop*2,sizeHeight)));
- input(cv::Rect(sizeCenter+sizeSide+sizeCrop,0,sizeSide-sizeCrop,sizeHeight)).copyTo(result(cv::Rect(sizeSide+sizeCenter-sizeCrop*3,0,sizeSide-sizeCrop,sizeHeight)) );
- cv::Mat sideFullImageBlend(sizeHeight,newSizeWeight,CV_32FC3,cv::Scalar(0,0,0));
- cv::Mat centerFullImageBlend(sizeHeight,newSizeWeight,CV_32FC3,cv::Scalar(0,0,0));
- result(cv::Rect(0,0,newSizeSide,sizeHeight)).copyTo(sideFullImageBlend(cv::Rect(0,0,newSizeSide,sizeHeight)));
- result(cv::Rect(newSizeCenter+newSizeSide,0,newSizeSide,sizeHeight)).copyTo(sideFullImageBlend(cv::Rect(newSizeSide,0,newSizeSide,sizeHeight)));
- result(cv::Rect(newSizeSide,0,newSizeCenter,sizeHeight)).copyTo(centerFullImageBlend(cv::Rect(newSizeSide*2,0,newSizeCenter,sizeHeight)));
- cv::Mat_<float> m(sideFullImageBlend.rows,sideFullImageBlend.cols,0.0);
- m(cv::Range::all(),cv::Range(0,newSizeCenter)) = 1.0;
- /*
- leftLapPyr= std::vector<cv::Mat_<cv::Vec3f>>();
- rightLapPyr=std::vector<cv::Mat_<cv::Vec3f>>();
- resultLapPyr=std::vector<cv::Mat_<cv::Vec3f>>();
- maskGaussianPyramid =std::vector<cv::Mat_<cv::Vec3f>>();
- left = sideFullImageBlend;
- right = centerFullImageBlend;
- blendMask = m;
- levels = 100;
- cv::Mat blendingResult=[OpenCVWrapper buildPyramid];
- blendingResult(cv::Rect(newSizeCenter,0,newSizeCenter,sizeHeight)).copyTo(result(cv::Rect(newSizeSide,0,newSizeCenter,sizeHeight)));
- blendingResult(cv::Rect(0,0,newSizeSide,sizeHeight)).copyTo(result(cv::Rect(0,0,newSizeSide,sizeHeight)));
- blendingResult(cv::Rect(newSizeSide,0,newSizeSide,sizeHeight)).copyTo(result(cv::Rect(newSizeCenter+newSizeSide,0,newSizeSide,sizeHeight)));
- */
- cv::resize(result,result,cv::Size(sizeWeight,sizeHeight));
- //m= cv::Mat_<float> (sideImageBlend.rows,sideImageBlend.cols,0.0);
- m(cv::Range::all(),cv::Range(0,sizeSide)) = 1.0;
- for(int i=1;i<=50;i++)
- {
- m(cv::Range::all(),cv::Range(sizeSide-i-1,sizeSide-i)) = 1-i/50;
- }
- leftLapPyr= std::vector<cv::Mat_<cv::Vec3f>>();
- rightLapPyr=std::vector<cv::Mat_<cv::Vec3f>>();
- resultLapPyr=std::vector<cv::Mat_<cv::Vec3f>>();
- maskGaussianPyramid =std::vector<cv::Mat_<cv::Vec3f>>();
- /*
- left = sideImageBlend;
- right = centerImageBlend;
- blendMask = m;
- levels = 10000;
- cv::Mat blendingResult=[OpenCVWrapper buildPyramid];
- */
- //blendingResult.copyTo(result(cv::Rect(0,0,sizeSide+sizeCenter,sizeHeight)));
- cv::Mat rightImageBlend(sizeHeight,sizeSide+sizeCenter,CV_32FC3,cv::Scalar(0,0,0));
- cv::Mat centerRightImageBlend(sizeHeight,sizeSide+sizeCenter,CV_32FC3,cv::Scalar(0,0,0));
- result(cv::Rect(sizeSide+sizeCenter,0,sizeSide,sizeHeight)).copyTo(rightImageBlend(cv::Rect(sizeCenter,0,sizeSide,sizeHeight)));
- result(cv::Rect(sizeSide,0,sizeCenter,sizeHeight)).copyTo(centerRightImageBlend(cv::Rect(0,0,sizeCenter,sizeHeight)));
- m(cv::Range::all(),cv::Range::all()) = 0.0;
- m(cv::Range::all(),cv::Range(0,sizeCenter)) = 1.0;
- for(int i=1;i<=50;i++)
- {
- m(cv::Range::all(),cv::Range(sizeCenter-i-1,sizeCenter-i)) = 1-i/50;
- }
- /*
- leftLapPyr= std::vector<cv::Mat_<cv::Vec3f>>();
- rightLapPyr=std::vector<cv::Mat_<cv::Vec3f>>();
- resultLapPyr=std::vector<cv::Mat_<cv::Vec3f>>();
- maskGaussianPyramid =std::vector<cv::Mat_<cv::Vec3f>>();
- left = centerRightImageBlend;
- right = rightImageBlend;
- blendMask = m;
- levels = 10000;
- blendingResult=[OpenCVWrapper buildPyramid];
- */
- // cv::cvtColor(blendingResult,blendingResult,CV_BGR2BGRA);
- cv::cvtColor(result,result,CV_BGR2BGRA);
- result.convertTo(result,CV_8UC4);
- //blendingResult.convertTo(blendingResult, CV_8UC4);
- //blendingResult.copyTo(result(cv::Rect(sizeSide,0,sizeSide+sizeCenter,sizeHeight)));
- cv::Mat leftBluring =result(cv::Rect(500,0,24,sizeHeight));
- cv::Mat rightBluring =result(cv::Rect(1524,0,24,sizeHeight));
- //cv::GaussianBlur(result(cv::Rect(500,0,24,sizeHeight)),leftBluring,cv::Size(21,21),0);
- //cv::GaussianBlur(result(cv::Rect(1524,0,24,sizeHeight)),rightBluring,cv::Size(21,21),0);
- //leftBluring.copyTo(result(cv::Rect(500,0,24,sizeHeight)));
- //rightBluring.copyTo(result(cv::Rect(1524,0,24,sizeHeight)));
- cv::Mat finalResult(sizeHeight,2038,CV_8UC4,cv::Scalar(0,0,0));
- int length = 5;
- int range = length*2;
- for(auto j = 0;j<sizeHeight;j++)
- {
- cv::Vec4b colorLeftBegin = result.at<cv::Vec4b>(cv::Point(sizeSide-length ,j));
- cv::Vec4b colorLeftEnd = result.at<cv::Vec4b>(cv::Point(sizeSide+length ,j));
- cv::Vec4b colorRightBegin = result.at<cv::Vec4b>(cv::Point(sizeSide+sizeCenter-length ,j));
- cv::Vec4b colorRightEnd = result.at<cv::Vec4b>(cv::Point(sizeSide+sizeCenter+length ,j));
- cv::Vec4b colorLeftRightBegin = result.at<cv::Vec4b>(cv::Point(sizeWeight-length ,j));
- cv::Vec4b colorLeftRightEnd = result.at<cv::Vec4b>(cv::Point(length ,j));
- for(float i =1;i<=range;i++ )
- {
- result.at<cv::Vec4b>(cv::Point(sizeSide-length+i,j)) = colorLeftBegin*(1-i/range)+colorLeftEnd*(i/range);
- result.at<cv::Vec4b>(cv::Point(sizeSide+sizeCenter-length+i,j)) = colorRightBegin*(1-i/range)+colorRightEnd*(i/range);
- /*
- if(length-i>=0)
- {
- result.at<cv::Vec4b>(cv::Point(length-i,j)) = colorLeftRightEnd*(1-i/range)+colorLeftRightBegin*(i/range);
- }
- else
- {
- result.at<cv::Vec4b>(cv::Point(sizeWeight+length-i,j)) = colorLeftRightEnd*(1-i/range)+colorLeftRightBegin*(i/range);
- }*/
- }
- }
- result(cv::Rect(0,0,510,sizeHeight)).copyTo(finalResult(cv::Rect(0,0,510,sizeHeight)));
- result(cv::Rect(514,0,1018,sizeHeight)).copyTo(finalResult(cv::Rect(510,0,1018,sizeHeight)));
- result(cv::Rect(1538,0,510,sizeHeight)).copyTo(finalResult(cv::Rect(1528,0,510,sizeHeight)));
- cv::resize(finalResult,finalResult,cv::Size(sizeWeight,sizeHeight));
- UIImage * resultImage = [UIImage imageWithCVMat:result];
- // inputBGR
- return resultImage;
- }
- +(UIImage *) compensateExposures:(UIImage*)firstPhoto :(UIImage*)secondPhoto :(UIImage*)firstMask :(UIImage*)secondMask
- {
- cv::Mat firstInput = firstPhoto.CVMat;
- cv::Mat secondInput = secondPhoto.CVMat;
- cv::Mat firstInputMask= firstMask.CVMat;
- cv::Mat secondInputMask = secondMask.CVMat;
- const std::vector<Point> corners(2);
- std::vector<cv::Mat> photos;
- photos.push_back(firstInput);
- photos.push_back(secondInput);
- std::vector<cv::Mat> masks;
- masks.push_back(firstInputMask);
- masks.push_back(secondInputMask);
- cv::Ptr<cv::detail::ExposureCompensator> compensator = cv::detail::ExposureCompensator::createDefault(cv::detail::ExposureCompensator::GAIN_BLOCKS);
- //compensator->feed(corners, photos, masks);
- return nil;
- }
- +(UIImage *) matchColors:(UIImage*)firstImage with:(UIImage*)secondImage
- {
- cv::Mat first = firstImage.CVMat;
- cv::Mat second = secondImage.CVMat;
- cv::Scalar m1, d1;
- cv::meanStdDev(first, m1, d1);
- cv::Scalar m2, d2;
- cv::meanStdDev(second, m2, d2);
- cv::Scalar mdiff = m1-m2;
- first -= mdiff;
- cv::Scalar m3, d3;
- cv::meanStdDev(first, m3, d3);
- UIImage * firstImageResult = [UIImage imageWithCVMat:first];
- first.release();
- second.release();
- return firstImageResult;
- }
- +(void) calibrateMaps:(bool)isFrontCamera {//:(float)dOne :(float)dTwo :(float)dThree :(float)dFour :(float)kOne :(float)kTwo :(float)kThree :(float)kFour {
- float K[3][3] = {
- {0,0,0},
- {0,0,0},
- {0,0,0}
- };
- if (isFrontCamera == false) {
- // K = {
- // {175, 0, 380}, // 175 380 // 380 480
- // {0, 134, 485}, // 134 485
- // {0, 0, 1}
- // };
- K[0][0] = 160;//175; // 170
- K[0][1] = 0;
- K[0][2] = 400;//380;
- K[1][0] = 0;
- K[1][1] = 136;//134;
- K[1][2] = 485;
- K[2][0] = 0;
- K[2][1] = 0;
- K[2][2] = 1;
- } else {
- K[0][0] = 204;
- K[0][1] = 0;
- K[0][2] = 380;
- K[1][0] = 0;
- K[1][1] = 200;
- K[1][2] = 480;
- K[2][0] = 0;
- K[2][1] = 0;
- K[2][2] = 1;
- }
- // float K[3][3] = {
- // {kOne, 0, kThree}, // 830 390
- // {0, kTwo, kFour},
- // {0, 0, 1}
- // };
- cv::Mat kMat(3, 3, CV_32FC1, K);
- //std::memcpy(kMat.data, K, 3*3*sizeof(float));
- float D[4] = {0, 0.165, 0, 0};
- //float D[4] = {dOne, dTwo, dThree, dFour};
- cv::Mat dMat(1, 4, CV_32FC1, D);
- //std::memcpy(dMat.data, D, 1*4*sizeof(float));
- cv::Mat Knew;
- kMat.copyTo(Knew);
- cv::fisheye::initUndistortRectifyMap(kMat, dMat, cv::Mat(), Knew, cv::Size(750, 1000), CV_32FC1, map1, map2);
- Knew.release();
- kMat.release();
- dMat.release();
- }
- +(UIImage *) undistortImage:(UIImage*)img
- {
- //cv::Mat image = img.CVMat;
- cv::Mat image = img.CVMatAlpha;
- cv::resize(image, image, cv::Size(750, 1000));
- cv::Mat undistortedImage;
- cv::remap(image, undistortedImage, map1, map2, cv::INTER_LINEAR, cv::BORDER_CONSTANT);
- //UIImage * result = [UIImage imageWithCVMat:undistortedImage];
- UIImage * result = [UIImage imageWithCVMatAlpha:undistortedImage];
- undistortedImage.release();
- image.release();
- return result;
- }
- +(UIImage *) resizeImageToNormalSize:(UIImage*)inputImage {
- cv::Mat image = inputImage.CVMat;
- cv::resize(image, image, cv::Size(2048, 1024));
- UIImage * result = [UIImage imageWithCVMatAlpha:image];
- image.release();
- return result;
- }
- +(float) calc_shift:(float)x1 :(float)x2 :(float)cx :(float)k
- {
- float thresh = 1;
- float x3 = x1+(x2-x1)*0.5f;
- float res1 = x1+((x1-cx)*k*((x1-cx)*(x1-cx)));
- float res3 = x3+((x3-cx)*k*((x3-cx)*(x3-cx)));
- if(res1 > -thresh && res1 < thresh) {
- return x1;
- }
- if(res3 < 0) {
- return [OpenCVWrapper calc_shift:x3 :x2 :cx :k];
- } else {
- return [OpenCVWrapper calc_shift:x1 :x3 :cx :k];
- }
- }
- +(float) getRadialX:(float)x :(float)y :(float)cx :(float)cy :(float)k :(bool)scale :(cv::Vec4f)props
- {
- float result;
- if (scale)
- {
- float xshift = props[0];
- float yshift = props[1];
- float xscale = props[2];
- float yscale = props[3];
- x = (x*xscale+xshift);
- y = (y*yscale+yshift);
- result = x+((x-cx)*k*((x-cx)*(x-cx)+(y-cy)*(y-cy)));
- } else {
- result = x+((x-cx)*k*((x-cx)*(x-cx)+(y-cy)*(y-cy)));
- }
- return result;
- }
- +(float) getRadialY:(float)x :(float)y :(float)cx :(float)cy :(float)k :(bool)scale :(cv::Vec4f)props
- {
- float result;
- if (scale)
- {
- float xshift = props[0];
- float yshift = props[1];
- float xscale = props[2];
- float yscale = props[3];
- x = (x*xscale+xshift);
- y = (y*yscale+yshift);
- result = y+((y-cy)*k*((x-cx)*(x-cx)+(y-cy)*(y-cy)));
- } else {
- result = y+((y-cy)*k*((x-cx)*(x-cx)+(y-cy)*(y-cy)));
- }
- return result;
- }
- +(void) fishEye:(cv::InputArray)_src :(cv::OutputArray)_dst :(double)Cx :(double)Cy :(double)k :(bool)scale
- {
- CV_Assert(Cx >= 0 && Cy >= 0 && k >= 0);
- cv::Mat src = _src.getMat();
- cv::Mat mapx(src.size(), CV_32FC1);
- cv::Mat mapy(src.size(), CV_32FC1);
- int w = src.cols;
- int h = src.rows;
- cv::Vec4f props;
- float xShift = [OpenCVWrapper calc_shift:0 :Cx-1 :Cx :k];
- props[0] = xShift;
- float newCenterX = w - Cx;
- float xShift2 = [OpenCVWrapper calc_shift:0 :newCenterX - 1 :newCenterX :k];
- float yShift = [OpenCVWrapper calc_shift:0 :Cy-1 :Cy :k];
- props[1] = yShift;
- float newCenterY = h - Cy; // !!!
- float yShift2 = [OpenCVWrapper calc_shift:0 :newCenterY - 1 :newCenterY :k];
- float xScale = (w-xShift-xShift2)/w;
- props[2] = xScale;
- float yScale = (h-yShift-yShift2)/h;
- props[3] = yScale;
- float* p = mapx.ptr<float>(0);
- for (int y = 0; y < h; y++)
- {
- for(int x = 0; x < w; x++)
- {
- *p++ = [OpenCVWrapper getRadialX:(float)x :(float)y :Cx :Cy :k :scale :props];
- }
- }
- p = mapy.ptr<float>(0);
- for (int y = 0; y < h; y++)
- {
- for(int x = 0; x < w; x++)
- {
- *p++ = [OpenCVWrapper getRadialY:(float)x :(float)y :Cx :Cy :k :scale :props];
- }
- }
- cv::remap(src, _dst, mapx, mapy, cv::INTER_LINEAR, cv::BORDER_CONSTANT);
- }
- +(UIImage *) distortImage:(UIImage*)img
- {
- cv::Mat undistortedImage = img.CVMatAlpha;
- cv::Mat distortedImage;
- [OpenCVWrapper fishEye:undistortedImage :distortedImage :undistortedImage.cols/2 :undistortedImage.rows/2 :0.001 :true];
- cv::Mat distortedImageWithoutAlpha;
- //cv::cvtColor(distortedImage, distortedImageWithoutAlpha, CV_RGBA2RGB);
- //UIImage * result = [UIImage imageWithCVMat:distortedImage];
- UIImage * result = [UIImage imageWithCVMatAlpha:distortedImage];
- return result;
- }
- +(UIImage *) removeBlackBackground:(UIImage*)img
- {
- cv::Mat src = img.CVMat;
- cv::Vec4b colorInPos = src.at<cv::Vec4b>(cv::Point(0,0));
- cv::Mat gray;
- cv::cvtColor(src, gray, CV_BGR2GRAY);
- cv::Mat mask;
- cv::threshold(gray, mask, 100, 255, CV_THRESH_BINARY);
- std::vector<cv::Mat> channels;
- cv::split(src, channels);
- channels.push_back(mask);
- cv::Mat dst;
- cv::merge(channels, dst);
- cv::Vec4b colorInDst = dst.at<cv::Vec4b>(cv::Point(0,0));
- UIImage * result = [UIImage imageWithCVMat:dst];
- return result;
- }
- +(UIImage *) addStickerToPanorama:(UIImage*)panorama :(UIImage*)sticker :(NSArray*)geoXPx :(NSArray*)geoYPx
- {
- cv::Mat stickerMat = sticker.CVMatAlpha;
- cv::Mat panoramaMat = panorama.CVMatAlpha;
- for (int i = 0; i < stickerMat.rows; i++) {
- for (int j = 0; j < stickerMat.cols; j++){
- NSArray *x = [geoXPx objectAtIndex: i];
- int xx = [(NSNumber*)[x objectAtIndex:j] intValue];
- NSArray *y = [geoYPx objectAtIndex: i];
- int yy = [(NSNumber*)[y objectAtIndex:j] intValue];
- //panoramaMat.at<cv::Point>(xx, yy) = stickerMat.at<cv::Point>(i,j);
- if (stickerMat.at<cv::Vec4b>(cv::Point(j,i))[3] != '\0') {
- panoramaMat.at<cv::Vec4b>(cv::Point(xx, yy)) = stickerMat.at<cv::Vec4b>(cv::Point(j, i));
- }
- }
- }
- UIImage * result = [UIImage imageWithCVMatAlpha:panoramaMat];
- return result;
- }
- //+(UIImage *) equirectToStereo:(UIImage*)img :(NSArray*)xe :(NSArray*)ye
- //{
- // cv::Mat input = img.CVMatAlpha;
- // cv::Mat output; //= input;
- // input.copyTo(output);
- //
- // for(int i = 0; i < input.cols; i++){
- // for(int j = 0; j < input.rows; j++){
- // NSArray *x = [xe objectAtIndex: i];
- // int xx = [(NSNumber*)[x objectAtIndex:j] intValue];
- // NSArray *y = [ye objectAtIndex: i];
- // int yy = [(NSNumber*)[y objectAtIndex:j] intValue];
- // output.at<cv::Vec3b>(cv::Point(xx, yy)) = input.at<cv::Vec3b>(cv::Point(i, j));
- // }
- // }
- //
- // UIImage * result = [UIImage imageWithCVMatAlpha:output];
- //
- // return result;
- //}
- +(UIImage *) renderProjection:(UIImage*)inputImage :(long)len
- {
- cv::Mat pano = inputImage.CVMat;
- cv::Mat convertedPano;
- pano.convertTo(convertedPano, CV_16UC3);
- cv::Mat output;
- output.create(len, len, CV_8UC4);
- long half_len = len/2;
- cv::Size sz = pano.size();
- double k_pi = 3.1415926535897932384626433832795;
- double k_pi_inverse = 0.31830988618379067153776752674503;
- for(long indexX = 0; indexX < len; ++indexX) {
- for(long indexY = 0; indexY < len; ++indexY){
- double sphereX = (indexX - half_len) * 10.0 / len;
- double sphereY = (indexY - half_len) * 10.0 / len;
- double Qx, Qy, Qz;
- if ([OpenCVWrapper getIntersection:sphereX :sphereY :&Qx :&Qy :&Qz])
- {
- double theta = std::acos(Qz);
- double phi = std::atan2(Qy, Qx) + k_pi;
- theta = theta * k_pi_inverse;
- phi = phi * (0.5 * k_pi_inverse);
- double Sx = cv::min(sz.width - 2.0, sz.width * phi);
- double Sy = cv::min(sz.height - 2.0, sz.height * theta);
- output.at<cv::Vec4b>(cv::Point(indexY, indexX)) = pano.at<cv::Vec4b>(cv::Point(Sx, Sy));//[OpenCVWrapper bilinearSample:convertedPano :Sx :Sy];
- }
- }
- }
- cv::Mat outputResult;
- output.convertTo(outputResult, CV_8UC4);
- cv::Mat outputResultBGR;
- //cv::cvtColor(outputResult, outputResultBGR, CV_BGR2RGB);
- UIImage * result = [UIImage imageWithCVMat:outputResult];
- return result;
- }
- +(bool) getIntersection:(double)u :(double)v :(double*)x :(double*)y :(double*)z
- {
- double Nx = 0.0;
- double Ny = 0.0;
- double Nz = 1.0;
- double dir_x = u-Nx;
- double dir_y = v-Ny;
- double dir_z = -1.0 - Nz;
- double a = (dir_x*dir_x) + (dir_y*dir_y) + (dir_z*dir_z);
- double b = (dir_x*Nx) + (dir_y*Ny) + (dir_z*Nz);
- b *= 2;
- double d = b*b;
- double q = -0.5 * (b-std::sqrt(d));
- double t = q/a;
- *x = (dir_x*t) + Nx;
- *y = (dir_y*t) + Ny;
- *z = (dir_z*t) + Nz;
- return true;
- }
- +(cv::Vec3s) bilinearSample:(cv::Mat)image :(double)x :(double)y
- {
- cv::Vec3s c00 = image.at<cv::Vec3s>((int)y, (int)x);
- cv::Vec3s c01 = image.at<cv::Vec3s>((int)y, (int)x+1);
- cv::Vec3s c10 = image.at<cv::Vec3s>((int)y+1, (int)x);
- cv::Vec3s c11 = image.at<cv::Vec3s>((int)y+1, (int)x+1);
- double X0 = x-floor(x);
- double X1 = 1.0 - X0;
- double Y0 = y-floor(y);
- double Y1 = 1.0 - Y0;
- double w00 = X0*Y0;
- double w01 = X1*Y0;
- double w10 = X0*Y1;
- double w11 = X1*Y1;
- // VOZMOJNO NAOBOROT BUDET(RGB)
- short r = (c00[2] + c01[2] + c10[2] + c11[2])/4;//(short)(c00[2] * w00 + c01[2] * w01 + c10[2]*w10 + c11[2]*w11);
- short g = (c00[1] + c01[1] + c10[1] + c11[1])/4;//(short)(c00[1] * w00 + c01[1] * w01 + c10[1]*w10 + c11[1]*w11);
- short b = (c00[0] + c01[0] + c10[0] + c11[0])/4;//(short)(c00[0] * w00 + c01[0] * w01 + c10[0]*w10 + c11[0]*w11);
- cv::Vec3s result = [OpenCVWrapper make_BGR:r :g :b];
- return result;
- }
- +(cv::Vec3s) make_BGR:(short)blue :(short)green :(short)red
- {
- cv::Vec3s result;
- result[0] = blue;
- result[1] = green;
- result[2] = red;
- return result;
- }
- +(UIImage *) addStickerToPanoImage:(UIImage*)pano :(UIImage*)sticker :(NSArray*)coordsToChange :(int)stickerWidth :(int)stickerHeight
- {
- cv::Mat inputPano = pano.CVMatAlpha;
- cv::Mat stickerMat = sticker.CVMatAlpha;
- cv::resize(stickerMat, stickerMat, cv::Size(stickerWidth, stickerHeight));
- for (int i = 0; i < stickerWidth; i++) {
- for (int j = 0; j < stickerHeight; j++) {
- NSArray *x = [coordsToChange objectAtIndex: i];
- NSArray *y = [x objectAtIndex: j];
- int xx = [(NSNumber*)[y objectAtIndex:0] intValue];
- int yy = [(NSNumber*)[y objectAtIndex:1] intValue];
- if (stickerMat.at<cv::Vec4b>(cv::Point(i, j))[3] != '\0') {
- inputPano.at<cv::Vec4b>(cv::Point(xx, yy)) = stickerMat.at<cv::Vec4b>(cv::Point(i, j));
- }
- }
- }
- // for(int x = 0; x < xToChange.count; x++){
- // for(int y = 0; y < yToChange.count; y++)
- // {
- // int xPos = [(NSNumber*)[xToChange objectAtIndex: x] intValue];
- // int yPos = [(NSNumber*)[yToChange objectAtIndex: y] intValue];
- // if (stickerMat.at<cv::Vec4b>(cv::Point(y, x))[3] != '\0') {
- // inputPano.at<cv::Vec4b>(cv::Point(xPos, yPos)) = stickerMat.at<cv::Vec4b>(cv::Point(y, x));
- // }
- // }
- // }
- UIImage * result = [UIImage imageWithCVMatAlpha:inputPano];
- return result;
- }
- +(UIImage *) getPanoScreenshot:(UIImage*)pano :(int)xStart :(int)xEnd :(int)yStart :(int)yEnd :(NSArray*)xToChange :(NSArray*)yToChange
- {
- cv::Mat inputPano = pano.CVMatAlpha;
- //int xSize = xEnd-xStart;
- //int ySize = yEnd-yStart;
- int xSize = xToChange.count;
- int ySize = yToChange.count;
- cv::Mat outputPano(ySize, xSize, CV_8UC4);
- for(int i = 0; i < ySize; i++) {
- for(int j = 0; j < xSize; j++) {
- int y = [(NSNumber*)[yToChange objectAtIndex: i] intValue];
- int x = [(NSNumber*)[xToChange objectAtIndex: j] intValue];
- outputPano.at<cv::Vec4b>(cv::Point(j,i)) = inputPano.at<cv::Vec4b>(cv::Point(x,y));
- }
- }
- UIImage * result = [UIImage imageWithCVMatAlpha:outputPano];
- return result;
- }
- //
- //+(cv::Mat) calculateLUT:(cv::Mat)in_cdf_mat :(cv::Mat)dst_cdf_mat {
- // int last = 0;
- // double epsilon = 0.01;
- // cv::Mat M(256, 1, CV_8UC1);
- // for(int j = 0; j < in_cdf_mat.rows; j++) {
- // double F1j = in_cdf_mat.ptr(j, 0)[0];
- // for(int k = last; k < dst_cdf_mat.rows; k++) {
- // double F2k = dst_cdf_mat.ptr(k, 0)[0];
- // if(abs(F2k-F1j) < epsilon || F2k > F1j) {
- // double data[1] = {(double)k};
- // M = cv::Mat(j, 0, CV_8UC1, data);
- // last = k;
- // break;
- // }
- // }
- // }
- // return M;
- //}
- //
- //+(cv::Mat) calculateCDF:(cv::Mat)channel :(cv::Mat)cdf {
- // cv::Mat cdfResult;
- // for (int i = 1; i < 256; i++) {
- // double data[1] = {0};
- // data[0] = cdf.at<double[]>(i-1, 0)[1] + channel.at<double[]>(i, 0)[0];
- // cdf = cv::Mat(i,0, CV_8UC1, data);
- // }
- // cdfResult = cdf;
- // return cdfResult;
- //}
- //
- //+(cv::Mat) calcHistogram:(cv::Mat)image :(cv::Mat)y_hist :(cv::Mat)y_cdf {
- // cv::Mat ycrcb;
- //
- // cv::cvtColor(image, ycrcb, CV_BGR2YCrCb);
- // image.release();
- //
- // std::vector<cv::Mat> ycrcbChannels;
- // cv::split(ycrcb, ycrcbChannels);
- //
- // std::vector<cv::Mat> yList;
- // yList.push_back(ycrcbChannels[0]);
- //
- // std::vector<int> histSize(256);
- // std::vector<float> histRange(0, 256);
- //
- // cv::calcHist(yList, std::vector<int>(0), cv::Mat(), y_hist, histSize, histRange);
- // cv::normalize(y_hist, y_hist, 3, cv::NORM_MINMAX);
- //
- // cv::Mat cdfFinal;
- //
- // cdfFinal = [OpenCVWrapper calculateCDF:y_hist :y_cdf];
- //
- // cv::normalize(cdfFinal, cdfFinal, 3, cv::NORM_MINMAX);
- //
- // ycrcb.release();
- //
- // return cdfFinal;
- //}
- //
- //+(void) transformLight:(cv::Mat)inputImage :(cv::Mat*)outputImage :(cv::Mat)ylut { // esli chto ybrat' *, peredavat kak &image
- // cv::Mat imageYCrCb;
- // cv::cvtColor(inputImage, imageYCrCb, CV_BGR2YCrCb);
- //
- // cv::Mat y_channel;
- // cv::extractChannel(imageYCrCb, y_channel, 0);
- // cv::Mat cr_channel;
- // cv::extractChannel(imageYCrCb, cr_channel, 1);
- // cv::Mat cb_channel;
- // cv::extractChannel(imageYCrCb, cb_channel, 2);
- //
- // cv::LUT(y_channel, ylut, y_channel);
- //
- // std::vector<cv::Mat> ycrcbDest;
- // ycrcbDest.push_back(y_channel);
- // ycrcbDest.push_back(cr_channel);
- // ycrcbDest.push_back(cb_channel);
- //
- // cv::merge(ycrcbDest, *outputImage);
- //
- // cv::cvtColor(*outputImage, *outputImage, CV_YCrCb2BGR);
- //
- // y_channel.release();
- // cr_channel.release();
- // cb_channel.release();
- // imageYCrCb.release();
- //}
- //
- //+(UIImage *) matchHistograms:(UIImage*)inputImage :(UIImage*)targetImage {
- // cv::Mat input_y_hist;
- // cv::Mat target_y_hist;
- // cv::Mat input = inputImage.CVMat;
- // cv::Mat target = targetImage.CVMat;
- // cv::Mat input_y_cdf;
- // cv::Mat target_y_cdf;
- //
- // input_y_cdf = [OpenCVWrapper calcHistogram:input :input_y_hist :input_y_cdf];
- // target_y_cdf = [OpenCVWrapper calcHistogram:input :target_y_hist :target_y_cdf];
- //
- // cv::Mat ylut = [OpenCVWrapper calculateLUT:input_y_cdf :target_y_cdf];
- //
- // cv::Mat dst;
- // [OpenCVWrapper transformLight:input :&dst :ylut];
- //
- // UIImage * resultImage = [UIImage imageWithCVMat:dst];
- //
- // input_y_hist.release();
- // target_y_hist.release();
- // input.release();
- // target.release();
- // input_y_cdf.release();
- // target_y_cdf.release();
- // ylut.release();
- //
- // return resultImage;
- //}
- +(UIImage *) equalizeIntensity:(UIImage*)inputImage {
- cv::Mat input = inputImage.CVMat;
- if(input.channels() >= 3) {
- cv::Mat ycrcb;
- cv::cvtColor(input, ycrcb, CV_BGR2YCrCb);
- std::vector<cv::Mat> channels;
- cv::split(ycrcb, channels);
- cv::equalizeHist(channels[0], channels[0]);
- cv::Mat result;
- cv::merge(channels, ycrcb);
- cv::cvtColor(ycrcb, result, CV_YCrCb2BGR);
- UIImage * resultImage = [UIImage imageWithCVMat:result];
- return resultImage;
- }
- return nil;
- }
- /////////
- +(void) do1ChnHist:(cv::Mat*)_i :(cv::Mat)mask :(double*)h :(double*)cdf {
- *_i = _i->reshape(1, 1);
- //cv::Mat _tm;
- //mask->copyTo(_tm);
- //mask = mask.reshape(1, 1);
- //for(int p = 0; p < _i->cols; p++) {
- // *h += 1.0;
- //}
- cv::Mat _tmp(1, 256, CV_64FC1, &h);
- double minVal, maxVal;
- cv::minMaxLoc(_tmp, &minVal, &maxVal);
- _tmp = _tmp / maxVal;
- cdf[0] = h[0];
- for(int j = 1; j < 256; j++) {
- cdf[j] = cdf[j-1]+h[j];
- }
- _tmp.data = (uchar*)cdf;
- cv::minMaxLoc(_tmp, &minVal, &maxVal);
- _tmp = _tmp / maxVal;
- //_i->release();
- // _tm.release();
- //_tmp.release();
- }
- +(UIImage *) histMatchRGB:(UIImage*)targetImage :(UIImage*)inputImage {
- cv::Mat srcMat = targetImage.CVMat;
- cv::Mat dstMat = inputImage.CVMat;
- cv::Mat src;
- cv::Mat dst;
- cv::cvtColor(srcMat, src, CV_BGRA2BGR);
- cv::cvtColor(dstMat, dst, CV_BGRA2BGR);
- cv::Mat src_mask;
- cv::Mat dst_mask;
- std::vector<cv::Mat> chns;
- cv::split(src, chns);
- std::vector<cv::Mat> chns1;
- cv::split(dst, chns1);
- cv::Mat src_hist = cv::Mat::zeros(1, 256, CV_64FC1);
- cv::Mat dst_hist = cv::Mat::zeros(1, 256, CV_64FC1);
- cv::Mat src_cdf = cv::Mat::zeros(1, 256, CV_64FC1);
- cv::Mat dst_cdf = cv::Mat::zeros(1, 256, CV_64FC1);
- cv::Mat Mv(1, 256, CV_8UC1);
- uchar *M = Mv.ptr<uchar>();
- for (int i = 0; i < 3; i++) {
- src_hist.setTo(cv::Scalar(0));
- dst_hist.setTo(cv::Scalar(0));
- src_cdf.setTo(cv::Scalar(0));
- dst_cdf.setTo(cv::Scalar(0));
- [OpenCVWrapper do1ChnHist:&chns[i] :src_mask :(double*)src_hist.data :(double*)src_cdf.data];
- [OpenCVWrapper do1ChnHist:&chns1[i] :dst_mask :(double*)dst_hist.data :(double*)dst_cdf.data];
- int last = 0;
- double *_src_cdf = src_cdf.ptr<double>();
- double *_dst_cdf = dst_cdf.ptr<double>();
- for (int j = 0; j < src_cdf.cols; j++) {
- double F1j = _src_cdf[j];
- for (int k = last; k < dst_cdf.cols; k++) {
- double F2k = _dst_cdf[k];
- if(cv::abs(F2k-F1j) < 1 || F2k > F1j) {
- M[j] = (uchar)k;
- last = k;
- break;
- }
- }
- }
- cv::Mat lut(1, 256, CV_8UC1, M);
- cv::LUT(chns[i], lut, chns[i]);
- lut.release();
- }
- src_cdf.release();
- dst_cdf.release();
- src_hist.release();
- src_mask.release();
- dst_hist.release();
- dst_mask.release();
- cv::Mat res;
- cv::merge(chns, res);
- res.copyTo(src);
- UIImage * resultImage = [UIImage imageWithCVMat:dst];
- res.release();
- src.release();
- dst.release();
- srcMat.release();
- dstMat.release();
- return resultImage;
- }
- +(UIImage *) pyramideBlend:(UIImage*)firstImage :(UIImage*)secondImage {
- return nil;
- }
- +(UIImage *) simplestCB:(UIImage*)inputPhoto :(float)percent {
- cv::Mat inputBGRA = inputPhoto.CVMat;
- cv::Mat input;
- cv::cvtColor(inputBGRA, input, CV_BGRA2BGR);
- CV_Assert(input.channels() == 3);
- CV_Assert(percent > 0 && percent < 100);
- float half_percent = percent / 200;
- std::vector<cv::Mat> tmpsplit;
- cv::split(input, tmpsplit);
- for(int i = 0; i<3; i++) {
- cv::Mat flat;
- tmpsplit[i].reshape(1, 1).copyTo(flat);
- cv::sort(flat, flat, CV_SORT_EVERY_ROW + CV_SORT_ASCENDING);
- int lowval = flat.at<uchar>(cvFloor(((float)flat.cols) * half_percent));
- int highval = flat.at<uchar>(cvCeil(((float)flat.cols) * (1 - half_percent)));
- tmpsplit[i].setTo(lowval, tmpsplit[i] < lowval);
- tmpsplit[i].setTo(highval, tmpsplit[i] > highval);
- cv::normalize(tmpsplit[i], tmpsplit[i], 0, 255, cv::NORM_MINMAX);
- }
- cv::Mat outputPhoto;
- cv::merge(tmpsplit, outputPhoto);
- UIImage * resultImage = [UIImage imageWithCVMat:outputPhoto];
- outputPhoto.release();
- input.release();
- inputBGRA.release();
- return resultImage;
- }
- +(UIImage *) removeGreen:(UIImage*)inputPhoto {
- cv::Mat dstPhoto = inputPhoto.CVMat;
- cv::Mat dst;
- cv::cvtColor(dstPhoto, dst, CV_BGRA2BGR);
- for(int i = 501; i < 1532; i++) {
- for(int k = 0; k < dst.rows; k++) {
- dst.at<cv::Vec3b>(cv::Point(i, k))[0] = (uchar)(cv::min(255, (int)((int)dst.at<cv::Vec3b>(cv::Point(i, k))[0] * 1.03 + 7)));
- dst.at<cv::Vec3b>(cv::Point(i, k))[1] = (uchar)(cv::min(255, (int)((int)dst.at<cv::Vec3b>(cv::Point(i, k))[1] * 0.95 + 7)));
- dst.at<cv::Vec3b>(cv::Point(i, k))[2] = (uchar)(cv::min(255, (int)((int)dst.at<cv::Vec3b>(cv::Point(i, k))[2] * 1.02 + 7)));
- }
- }
- for(int i = 0; i < 501; i++) {
- for (int k = 0; k < dst.rows; k++) {
- dst.at<cv::Vec3b>(cv::Point(i, k))[0] = (uchar)(cv::min(255, (int)((int)dst.at<cv::Vec3b>(cv::Point(i, k))[0] * 1.01 + 7)));
- dst.at<cv::Vec3b>(cv::Point(i, k))[1] = (uchar)(cv::min(255, (int)((int)dst.at<cv::Vec3b>(cv::Point(i, k))[1] * 0.96 + 7)));
- dst.at<cv::Vec3b>(cv::Point(i, k))[2] = (uchar)(cv::min(255, (int)((int)dst.at<cv::Vec3b>(cv::Point(i, k))[2] * 1.02 + 7)));
- }
- }
- for(int i = 1532; i < 2048; i++) {
- for (int k = 0; k < dst.rows; k++) {
- dst.at<cv::Vec3b>(cv::Point(i, k))[0] = (uchar)(cv::min(255, (int)((int)dst.at<cv::Vec3b>(cv::Point(i, k))[0] * 1.01 + 7)));
- dst.at<cv::Vec3b>(cv::Point(i, k))[1] = (uchar)(cv::min(255, (int)((int)dst.at<cv::Vec3b>(cv::Point(i, k))[1] * 0.96 + 7)));
- dst.at<cv::Vec3b>(cv::Point(i, k))[2] = (uchar)(cv::min(255, (int)((int)dst.at<cv::Vec3b>(cv::Point(i, k))[2] * 1.02 + 7)));
- }
- }
- UIImage * resultImage = [UIImage imageWithCVMat:dst];
- dstPhoto.release();
- dst.release();
- return resultImage;
- }
- +(UIImage *) fixSaturation:(UIImage*)inputPhoto {
- cv::Mat dstPhoto = inputPhoto.CVMat;
- cv::Mat dstBGR;
- cv::cvtColor(dstPhoto, dstBGR, CV_BGRA2BGR);
- cv::Mat dstHSV;
- cv::cvtColor(dstBGR, dstHSV, CV_BGR2HSV);
- for(int i = 0; i < dstHSV.cols; i++) {
- for(int k = 0; k < dstHSV.rows; k++) {
- dstHSV.at<cv::Vec3b>(cv::Point(i,k))[1] = (uchar)((int)dstHSV.at<cv::Vec3b>(cv::Point(i,k))[1] * 1.02);
- dstHSV.at<cv::Vec3b>(cv::Point(i,k))[2] = (uchar)((int)dstHSV.at<cv::Vec3b>(cv::Point(i,k))[1] * 0.8);
- }
- }
- cv::Mat resultMat;
- cv::cvtColor(dstHSV, resultMat, CV_HSV2BGR);
- UIImage * resultImage = [UIImage imageWithCVMat:resultMat];
- dstPhoto.release();
- resultMat.release();
- dstHSV.release();
- return resultImage;
- }
- @end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement