Opencv Java 直方圖 傅里葉變換

Java 版本: JavaCVjava

用OpenCV讀一張圖片並顯示。只需將程序運行時的截圖回覆。如何安裝配置建立項目編寫OpenCV代碼,可參考何東健課件和源代碼或其餘資源。數組

1. 用OpenCV讀一張圖片,顯示該圖的直方圖。只需截圖回覆。如何安裝配置建立項目編寫OpenCV代碼,可參考何東健課件和源代碼的第3章或其餘資源。
2. 用OpenCV讀一張圖片,求該圖的離散傅立葉變換,並顯示其頻譜。只需截圖回覆。如何安裝配置建立項目編寫OpenCV代碼,可參考何東健課件和源代碼的第5章或其餘資源。
3. 雖然咱們是以OpenCV來佈置實踐,可是若是同窗們採用其餘方式,也是能夠的,好比使用Matlab等等。只要能把問題解決。不一樣的途徑有不一樣的特色,在實踐過程當中同窗們能夠去體會。
4. 對第3章理論內容,只要求同窗們瞭解會用便可,若是想進一步瞭解相關內容,同窗們能夠參考數字信號處理相關書籍或者其餘數字圖像處理書籍。函數

直方圖ui


/** * @program: learn-opencv * @description: 繪製圖片直方圖 * @author: Mr.Dai * @create: 2020-03-03 16:30 **/
public class Histogram { private final  static String path=System.getProperty("user.dir")+"\\catton.jpg"; static{ platformUtils.loadLibraries(); } public static void main(String[] args) { Mat imread = Imgcodecs.imread(path); HighGui.imshow(" 原圖像",imread); plotGrayHistogram(imread); // 無限等待按鍵按下
        HighGui.waitKey(0); } public static void plotGrayHistogram(Mat img) { java.util.List<Mat> images = new ArrayList<>(); images.add(img); MatOfInt channels = new MatOfInt(0); // 圖像通道數,0表示只有一個通道
        MatOfInt histSize = new MatOfInt(256); // CV_8U類型的圖片範圍是0~255,共有256個灰度級
        Mat histogramOfGray = new Mat(); // 輸出直方圖結果,共有256行,行數的至關於對應灰度值,每一行的值至關於該灰度值所佔比例
        MatOfFloat histRange = new MatOfFloat(0, 255); Imgproc.calcHist(images, channels, new Mat(), histogramOfGray, histSize, histRange, false);  // 計算直方圖 // 按行歸一化
        Core.normalize(histogramOfGray, histogramOfGray, 0, histogramOfGray.rows(), Core.NORM_MINMAX, -1, new Mat()); // 建立畫布
        int histImgRows = 300; int histImgCols = 300; int colStep = (int) Math.floor(histImgCols / histSize.get(0, 0)[0]); Mat histImg = new Mat(histImgRows, histImgCols, CvType.CV_8UC3, new Scalar(255,255,255));  // 從新建一張圖片,繪製直方圖
        for (int i = 0; i < histSize.get(0, 0)[0]; i++) {  // 畫出每個灰度級份量的比例,注意OpenCV將Mat最左上角的點做爲座標原點
 Imgproc.line(histImg, new org.opencv.core.Point(colStep * i, histImgRows - 20), new org.opencv.core.Point(colStep * i, histImgRows - Math.round(histogramOfGray.get(i, 0)[0]) - 20), new Scalar(0, 0,0), 2,8,0); if (i%50 == 0) { Imgproc.putText(histImg, Integer.toString(i), new org.opencv.core.Point(colStep * i, histImgRows - 5), 1, 1, new Scalar(0, 0, 0));  // 附上x軸刻度
 } } //顯示出來 對namedWindos 與cv::imshow 封裝
        HighGui.imshow("Gray Histogram",histImg); } }




image_thumb1

傅里葉:url

/** * @Description: 傅里葉變換 * @Author: Dai.GuoWei * @Date: 2020/3/3 */
public class TestDft { public Mat dftStart(Mat img) { img.convertTo(img, CvType.CV_32FC1); System.out.println("img類型: " + img.type() + " " + img.channels()); int M = Core.getOptimalDFTSize(img.rows()); // 得到最佳DFT尺寸,爲2的次方
        int N = Core.getOptimalDFTSize(img.cols()); // 同上
        Mat padded = new Mat(); System.out.println("padded 類型: " + padded.size() + " " + padded.type() + " " + padded.channels()); Core.copyMakeBorder(img, padded, 0, M - img.rows(), 0, N - img.cols(), Core.BORDER_CONSTANT, new Scalar(0)); // opencv中的邊界擴展函數,提供多種方式擴展
        System.out.println("padded 類型: " + padded.size() + " " + padded.type() + " " + padded.channels()); System.out.println("padded 類型: " + padded.size() + " " + padded.type() + " " + padded.channels()); List<Mat> planes = new ArrayList<Mat>(); // Mat 數組,第一個爲擴展後的圖像,一個爲空圖像,
 planes.add(padded); planes.add(Mat.zeros(padded.size(), CvType.CV_32FC1)); Mat complexImg = new Mat(); System.out .println("complexImg 類型: " + complexImg.size() + " " + complexImg.type() + " " + complexImg.channels()); Core.merge(planes, complexImg); // 合併成一個Mat
 System.out .println("complexImg 類型: " + complexImg.size() + " " + complexImg.type() + " " + complexImg.channels()); Core.dft(complexImg, complexImg); // FFT變換, dft須要一個2通道的Mat // compute log(1 + sqrt(Re(DFT(img))**2 + Im(DFT(img))**2))
        Core.split(complexImg, planes); // 分離通道, planes[0] 爲實數部分,planes[1]爲虛數部分
        Core.magnitude(planes.get(0), planes.get(1), planes.get(0)); // 求模
        Mat mag = planes.get(0); Core.add(mag, new Scalar(1), mag); // mag += new Scalar(1); 
        Core.log(mag, mag); // 模的對數 // crop the spectrum, if it has an odd number of rows or columns
        mag = new Mat(mag, new Rect(0, 0, mag.cols() & -2, mag.rows() & -2)); // 保證偶數的邊長

        int cx = mag.cols() / 2; int cy = mag.rows() / 2; // rearrange the quadrants of Fourier image //對傅立葉變換的圖像進行重排,4個區塊,從左到右,從上到下 // 分別爲q0, q1, q2, q3 // so that the origin is at the image center // 對調q0和q3, q1和q2
        Mat tmp = new Mat(); Mat q0 = new Mat(mag, new Rect(0, 0, cx, cy)); Mat q1 = new Mat(mag, new Rect(cx, 0, cx, cy)); Mat q2 = new Mat(mag, new Rect(0, cy, cx, cy)); Mat q3 = new Mat(mag, new Rect(cx, cy, cx, cy)); q0.copyTo(tmp); q3.copyTo(q0); tmp.copyTo(q3); q1.copyTo(tmp); q2.copyTo(q1); tmp.copyTo(q2); // Core.normalize(mag, mag, 0, 255, Core.NORM_MINMAX); // 規範化值到 0~1 顯示圖片的須要 歸一化
        Core.normalize(mag,mag, 0, 255, Core.NORM_MINMAX,CvType.CV_8UC1,new Mat()); System.out.println("mag 類型: " + mag.size() + " " + mag.type() + " " + mag.channels()); mag.convertTo(mag, CvType.CV_8U); return mag; } private final  static String path=System.getProperty("user.dir")+"\\catton.jpg"; static{ platformUtils.loadLibraries(); } public static void main(String[] args) { Mat img = Imgcodecs.imread(path); Mat gray = new Mat(); Imgproc.cvtColor(img, gray, Imgproc.COLOR_RGB2GRAY); TestDft t = new TestDft(); Mat dst = t.dftStart(gray); HighGui.imshow("原圖", img); HighGui.imshow("dft效果圖", dst); HighGui.waitKey(0); HighGui.destroyAllWindows(); System.exit(0); } }
image_thumb3
相關文章
相關標籤/搜索