2015-02-06 10:19:40 xiaojun111111 阅读数 1408

由于时间关系这里先暂且贴上必要算法的代码;

//获取一个矩形区域中的子区域
void COpencvDlg::GetClipRect(CPoint point, LPRECT lpRect,int d)
{
 CRect rect ;
 rect=*lpRect ;

 lpRect->left=point.x-d ;
 lpRect->top=point.y-d ;

 if(lpRect->left<0)
  lpRect->left=0 ;
 if(lpRect->top<0)
  lpRect->top=0 ;

 lpRect->right=lpRect->left+2*d ;
 lpRect->bottom=lpRect->top+2*d ;
 if(lpRect->bottom>rect.bottom)
 {
  lpRect->top=rect.bottom-2*d ;
  lpRect->bottom=rect.bottom ;
 }
 if(lpRect->right>rect.right)
 {
  lpRect->left=rect.right-2*d ;
  lpRect->right=rect.right ;
 }
}

 

void COpencvDlg::ProcessMouseMove(int nFlags, CPoint point)
{
 CPoint mPoint1,mPoint2 ;
 CPoint mTemp ;
 CDC *pDc ;
 CRect rect ;
 CvRect rect1 ;
 CvvImage cimg1 ;
 float xScale,yScale ;
 int xOffset,yOffset ;
 CvSize size ;
 IplImage *pTemp ;
 mPoint1.x=0 ;
 mPoint1.y=0 ;
 mPoint2.x=0 ;
 mPoint2.y=0 ;
 GetDlgItem(IDC_STATIC)->ClientToScreen(&mPoint1) ;
 GetDlgItem(IDC_STATIC)->GetClientRect(&rect) ;
 ClientToScreen(&mPoint2) ;
 xOffset=mPoint1.x-mPoint2.x ;
 yOffset=mPoint1.y-mPoint2.y ;
 if(pImage!=NULL)
 {
  xScale=(float)(pImage->width)/(rect.right-rect.left) ;
  yScale=(float)(pImage->height)/(rect.bottom-rect.top) ;
 }
 mTemp.x=point.x-xOffset ;
 mTemp.y=point.y-yOffset ;
 if((mTemp.x<rect.right)&&(mTemp.y<rect.bottom)&&(mTemp.x>=0)&&(mTemp.y>=0))
 {//当且仅当在图像显示区域时,捕捉鼠标移动事件
  this->GetClipRect(mTemp,&rect,dd) ;
  pDc=GetDlgItem(IDC_STATIC)->GetDC() ;
 // pDc->Rectangle(&rect) ;
  if(pImage!=NULL)
  {
   this->OnPaint() ;
   rect1.x=rect.left*xScale ;
   rect1.y=rect.top*yScale ;
   rect1.width=2*dd*xScale ;
   rect1.height=2*dd*yScale ;//注意这里由于图像大小与显示区域不一致,所以我们要将坐标转化为像素坐标
   cvSetImageROI(pImage ,rect1) ;
   GetDlgItem(IDC_STATIC)->GetClientRect(&rect) ;
   this->GetClipRect(mTemp,&rect,dd*scale) ;
   size.width=rect.right-rect.left ;
   size.height=rect.bottom-rect.top ;
   pTemp=cvCreateImage(size,pImage->depth,pImage->nChannels) ;
   cvResize(pImage,pTemp) ;
   cimg1.CopyOf(pTemp) ;
   cvResetImageROI(pImage) ;

   cimg1.DrawToHDC(pDc->m_hDC,rect) ;
   cvReleaseImage(&pTemp) ;
  }
 }

}

2019-03-23 16:36:53 weixin_39444746 阅读数 864

科研必备之图像局部区域放大(Matlab或QT实现)

在撰写图像处理领域相关的论文中通常需要将图片的某个小块进行放大,以便论文审稿者看到图像清晰的细节信息,本文主要使用matlab和QT(需要搭建opencv)来实现此种效果。

Matlab版本

function [ dest ] = draw_rect(src, startPosition, rectSize, lineSize, color)

[start_y, start_x] = deal(startPosition(1),startPosition(2));		% start position
[rect_size_w, rect_size_h] = deal(rectSize(1),rectSize(2));			% Rect Size

[width, height, channel] = size(src);
if channel==1
    dest(:, : ,1) = src;
    dest(:, : ,2) = src;
    dest(:, : ,3) = src;
else
    dest = src;
end

for channel_i = 1 : 3              
    for line_i = 1 : lineSize		% expand inside
	gain = line_i-1;
         dest(start_y+gain, (start_x+gain):(start_x+rect_size_w-gain),  channel_i ) =  color(channel_i);				%above
         dest(start_y+rect_size_h-gain,  (start_x+gain):(start_x+rect_size_w-gain), channel_i ) =  color(channel_i);	%bottom
         dest((start_y+gain):(start_y+rect_size_h-gain),  start_x+gain, channel_i ) =  color(channel_i);				%left
         dest((start_y+gain):(start_y+rect_size_h-gain),  start_x+rect_size_w-gain, channel_i ) =  color(channel_i);	%right
    end    
end 

QT版本(含界面)

void MainWindow::on_pushButton_2_clicked()
{
    int start_h = 220, start_w = 180;
    int rectSize = 50, scaleSize=3;
    Rect rect1 = Rect(start_h, start_w, rectSize, rectSize);        // specific rect
    Mat srcImage = imread("/home/mark/Sofeware/Qt/Qt_Project/QtApplication2/QT_DrawRect/lena.png");
    Mat imageRect = srcImage;
    cvtColor(imageRect, imageRect, CV_BGR2RGB);     // convert the BGR image to RGB
    Mat image_ROI = imageRect(rect1);    // define the ROI area and magnification ROI area
    Mat image_scaleROI;
    cv::resize(image_ROI, image_scaleROI, Size(scaleSize*rectSize, scaleSize*rectSize));
    Rect rect2 = Rect(imageRect.rows-image_scaleROI.rows, imageRect.cols-image_scaleROI.cols,  // magnification rect
                      image_scaleROI.rows, image_scaleROI.cols);
    image_scaleROI.copyTo(imageRect(rect2));        // cover the scaled ROI area
    rectangle(imageRect, rect1, cvScalar(255,0,0),2);  // draw two rect
    rectangle(imageRect, rect2, cvScalar(255,0,0),2);
    QImage image((const uchar*)imageRect.data, imageRect.cols, imageRect.rows,       // show image in Qlabel
                     imageRect.cols*imageRect.channels(), QImage::Format_RGB888);
    QImage showImage = image.scaled(ui->label->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
    ui->label->setPixmap(QPixmap::fromImage(showImage));
    cvtColor(imageRect, imageRect, CV_RGB2BGR);
    imwrite("/home/mark/Sofeware/Qt/Qt_Project/QtApplication2/QT_DrawRect/output.png", imageRect);
}

最终应用两种方法得到的测试结果为:

完整的代码工程文件请前往github下载
https://github.com/RussellEven/Draw_Rect

转载须知:https://blog.csdn.net/weixin_39444746/article/details/88763550

2019-04-26 17:31:27 IKMIC 阅读数 137

在网上找了很多,没有找到比较合适的,所以决定自己在前人的基础上进行一些改善。

   
      protected  static Bitmap change2bitmap(Bitmap mbitmap) {
          int width = mbitmap.getWidth();
          int height = mbitmap.getHeight();
          int pixR = 0;
          int pixG = 0;
          int pixB = 0;
          int newR = 0;
          int newG = 0;
          int radius=700;//半径
          double dis =0.0;
          int newB = 0;
          int buf[] =new int[width * height];
          int centerX = 500;
          int centerY =1100;//圆心坐标
          int pixels[]=new int[width * height];
         mbitmap.getPixels(buf, 0, width, 0, 0, width, height);
          for (int i = 0; i < width; i++)
          {
              for (int j = 0; j < height; j++)
              {
                  int arrl_color = buf[j * width + i];
                  pixR = red(arrl_color);
                  pixG = green(arrl_color);
                  pixB = blue(arrl_color);
                  newR = pixR;
                  newG = pixG;
                  newB = pixB;
                   int   distance =  ((centerX - i) * (centerX - i) + (centerY - j) * (centerY - j));
                  dis=Math.sqrt(distance);
                  if (distance <= radius * radius)
                  {

                      int src_x1 = i - centerX;
                      int src_y1 = j - centerY;
                      int  src_x = (int)((dis/radius /2+0.5)*src_x1);
                      int  src_y = (int)((dis/radius /2+0.5)*src_y1);
                      src_x = src_x+ centerX;
                      src_y = src_y + centerY;
                      int src_color = buf[src_y * width + src_x];
                      newR = red(src_color);
                      newG = green(src_color);
                      newB = blue(src_color);

                  }

                  newR = Math.min(255, Math.max(0, newR));
                  newG = Math.min(255, Math.max(0, newG));
                  newB = Math.min(255, Math.max(0, newB));
                  pixels[width * j + i] = Color.argb(255, newR, newG, newB);
              }
          }



          mbitmap = Bitmap.createBitmap(pixels, width, height, Bitmap.Config.ARGB_4444);
          return mbitmap;


      }

  }

重点代码如下:
int src_x1 = (int) ((float) (i - centerX) );
int src_y1 = (int) ((float) (j - centerY)
int src_x = (int)((dis/radius /2+0.5)*src_x1);
int src_y = (int)((dis/radius /2+0.5)*src_y1);
src_x = src_x+ centerX;
src_y = src_y + centerY;
算法主要用到的还是一元二次方程,
相比较之前算法扩散范围变小,
扩散幅度由一元二次方程A值进行调控。
未调整前:
在这里插入图片描述
调整后:
在这里插入图片描述

2019-12-16 18:31:24 luanhaotian 阅读数 8

是的,windows 是有放大镜功能, 但是局部放大某指定区域显示麻烦了,

并且,有用图像处理的取色,还要调用其它的“抓一抓”或PS,

此程序决定了以上问题!!!

 
取色:
 
局部放大
 
 
声明:没有病毒!!!
 
 
链接: https://pan.baidu.com/s/1IzRoXqq9TwDS2lDwS7uiJA 提取码: 96c4
2017-04-18 21:20:12 u013085897 阅读数 17962
       现在很多图像美颜app,处理后不但使人物皮肤变得平滑、白皙,还会稍微瘦下脸、放大眼睛,给人眼前一亮的感觉。这其中涉及人脸检测及特征点提取算法,一般提取68个特征点就足够了,同时也涉及图像局部变形算法。这也是两个研究方向,前者主要是计算机视觉,后者是图像处理。但随着深度学习的大热及在多个领域的成功应用,很多图像处理技术也开始采用深度学习算法实现突破,比如基于深度学习的降噪、超分辨率、非真实感绘制等等技术。深度学习大有在计算机视觉、图像处理一统之态势。言归正传,本文主要还是介绍瘦脸及放大眼睛所用到的图像局部变形算法。主要参考:交互式图像变形算法一文 。看过该文章后,自然了解瘦脸其实用的是图像局部平移变形,放大眼睛,用的是图像局部缩放变形。同时,文章还阐述了图像局部旋转变形的算法原理及思路。
       瘦脸及放大眼睛的前提是需要检测到人脸,并提取特征点。谈到图像变形,最基础的思路是:由变形前坐标,根据变形映射关系,得到变形后坐标。这其中变形映射关系是最关键的,不同的映射关系,将得到不同的变形效果。平移、缩放、旋转,对应的是不同的映射关系,即不同的变换公式。当然实际在计算过程中,用的是逆变换,即由变形后坐标,根据逆变换公式反算变形前坐标,然后插值得到该坐标rgb像素值,将该rgb值作为变形后坐标对应的像素值。这样才能保证变形后的图像是连续、完整的。

       下面简单讲一下图像局部平移变形,该变形稍微复杂一些,公式如下:

                                       

       公式中,由于主要是像素点位置计算,因此涉及一些矢量运算,不过比较简单。其实上面公式就是逆变换公式了,x是变换后的位置,u是原坐标位置。整个计算在以c为圆心,r为半径的圆内进行。因为是交互式图像局部变形,所以c也可以看做鼠标点下时的坐标,而m为鼠标移动一段距离后抬起时的坐标,这样c和m就决定了变形方向。下面是示例代码,公式结合代码一起看,应该很快能弄明白。
void LocalTranslationWarp(Mat &img, int warpX, int warpY, int warpW, int warpH, int directionX, int directionY, double warpCoef)
{
	RestrictBounds(warpX, warpY, warpW, warpH);

	Mat imgCopy;
	copyMakeBorder(img, imgCopy, 0, 1, 0, 1, BORDER_REPLICATE);

	Point center(warpX + (warpW>>1), warpY + (warpH>>1));
	double radius = (warpW < warpH) ? (warpW >> 1) : (warpH >> 1);
	radius = radius * radius;

	// 平移方向矢量/模
	double transVecX = directionX - center.x;
	double transVecY = directionY - center.y;
	double transVecModel = transVecX*transVecX + transVecY*transVecY;

	// 水平/垂直增量//映射后位置与原位置
	double dx = 0, dy = 0, posX = 0.0, posY = 0.0, posU = 0.0, posV = 0.0;
	// 点到圆心距离/平移比例
	double distance = 0.0, ratio = 0.0;
	// 插值位置
	int startU = 0, startV = 0;
	double alpha = 0.0, beta = 0.0;

	int maxRow = warpY + warpH;
	int maxCol = warpX + warpW;
	uchar* pImg = NULL;
	for (int i = warpY; i < maxRow; i++)
	{
		pImg = img.data + img.step * i;
		for (int j = warpX; j < maxCol; j++)
		{
			posX = j;
			posY = i;
			dx = posX - center.x;
			dy = posY - center.y;
			distance = dx*dx + dy*dy;
			if (distance < radius)
			{
				ratio = (radius - distance) / (radius - distance + transVecModel * warpCoef);
				posU = posX - ratio * ratio * transVecX;
				posV = posY - ratio * ratio * transVecY;

				startU = (int)posU;
				startV = (int)posV;
				alpha = posU - startU;
				beta  = posV - startV;
				BilinearInter(imgCopy, startU, startV, alpha, beta, pImg[3*j], pImg[3*j + 1], pImg[3*j + 2]);
			}
		}
	}
}
       可以看到,只有圆形选区内的图像才进行变形。越靠近圆心,变形越大,反之变形越小。对于图像缩放变形及旋转变形,公式比较简单,实现起来也容易一些,本文就不在详细讲解了。应用上面算法,简单的瘦脸效果如下:
    

       
       参考文献:



图像处理的哈哈镜

阅读数 2471

没有更多推荐了,返回首页